pcregrep para encontrar linhas com espaço em branco circundante [fechado]

3

Esta questão é semelhante a: Usando o grep para identificar títulos incorretos .

Eu tenho alguns títulos que começam com # (como são markdown), e eu tenho as duas regras a seguir:

  • títulos ( # ) devem ter exatamente duas linhas de linhas novas acima e uma abaixo
  • as legendas ( ## , ### e assim por diante) devem ter exatamente uma linha em branco acima e outra abaixo.
  • Os títulos devem ter precedência sobre as legendas. (Se houver duas regras conflitantes, use a formatação do título e ignore as legendas).

OBSERVAÇÃO: Estou tentando encontrar todos os títulos que não estão em conformidade com essas três restrições.

Abaixo estão alguns exemplos de bons e maus títulos

some text 
# Title     | BAD 

## Subtitle | Good (Has two spaces below, is needed for next main title)


# Title     | Good

## Subtitle | Bad
text  

# Title     | Bad

text

Depois de brincar com o regexp, descobri estas expressões:

Títulos principais: Regexr

((?<=\n{4})|(?<=.\n{2})|(?<=.\n))(# .*)|(# .*)(?=(\n.|\n{3}(?!# )|\n{4}))

Legendas: Regex

'((?<=\n{3})|(?<=.\n))(##+.*)|(##+.*)(?=\n.|\n{3}(?!# )|\n{4}.)'

No entanto, para minha grande confusão, eles não funcionam com pcregrep ? Aqui está o comando que eu tentei executar com pcgrep (apenas por causa da integralidade):

$ pcregrep -rniM --include='.*\.md' \
     '((?<=\n{3})|(?<=.\n))(##+.*)|(##+.*)(?=\n.|\n{3}(?!# )|\n{4}.)' \
     ~/Programming/oppgaver/src/web

Também não funciona quando tento pesquisar apenas um arquivo e tenho outras expressões que funcionam bem.

Há algo errado com meu regex , ou é uma implementação defeituosa?

    
por Øistein Søvik 15.07.2018 / 19:24

1 resposta

1

Esta solução corrige todos os títulos certos.

sed -r '
    :loop; N; $!b loop

    s/\n+(#[^\n]+)/\n\n/g

    s/(#[^\n]+)\n+/\n\n/g

    s/\n+(#[^\n#]+)/\n\n\n/g
' input.txt;

Com comentários:

sed -r '
    ### put all file into the pattern space,
    # in other words, merge all lines into one line
    :loop; N; $!b loop;

    ### first traversal of the pattern space
    # searches the line with "#" sign (all cases matches - Titles, SubTitles, etc),
    # takes all its upper empty lines
    # and converts them to the one empty line 
    s/\n+(#[^\n]+)/\n\n/g;


    ### second traversal of the pattern space
    # again, searches the line with "#" sign, take all its bottom empty lines
    # and converts them to the one empty line 
    s/(#[^\n]+)\n+/\n\n/g;

    ### third traversal of the pattern space
    # searches the single "#" sign (Titles only),
    # takes all its upper newlines (at this moment only two of them are there,
    # because of previous substitutions) 
    # and converts them to three newlines 
    s/\n+(#[^\n#]+)/\n\n\n/g
' input.txt

Entrada

text
# Title
## SubTitle
### SubSubTitle
# Title
## SubTitle
text
### SubSubTitle
# Title
# Title
# Title
## SubTitle
### SubSubTitle

Resultado

text


# Title

## SubTitle

### SubSubTitle


# Title

## SubTitle

text

### SubSubTitle


# Title


# Title


# Title

## SubTitle

### SubSubTitle
    
por 16.07.2018 / 16:14

Tags