pt sed regexp processamento de texto captura agrupamento referenciando alternância confusão

5

O agrupamento de captura de sed ALTERNATION não está funcionando como esperado.

Enquanto a alternância tem a menor precedência, aqui está a confusão:

echo "abcd_aefghi" | sed -r "s/(a)(b)(c)(d)|(a)(e)(f)(g)//g;"

observed result --> _ghi
expected result --> error: invalid reference  RHS

a--bcd | # Logical alternation (Not bitwise!!)
#must be different separated logical state processing!! 
#not involvement of look behind registered reference grouping Counting!!
a--efg ;

também

sed -r "s/(a)((b)(c)(d)|(e)(f)(g))//;"
observed result --> _ghi

mais confusão se

sed -r "s/(a)(b)(c)(d)()|((a)(e)(f)(g))//g"

observed result --> _ehi

também mais confusão

sed -r "s/(a)(b)(c)(d)()||||i am Not comment, Whats going here?|||||||((a)(e)(f)(g))//g"

observed result --> _ehi
expected result --> full parsing error, because "||"

pior é para agrupamento dentro de correspondência

echo "aBcB_aCfC" | sed -r "s/(a)((B)(c)()|(C)(f)())//g;"
#Infield twin uppercase's must match!
observed result --> aBcB_aCfC
expected result --> c_f

perl -pe repete o mesmo problema!

O problema é que a contagem de referências vai além do escopo de alternância, em vez de redefinir a contagem depois de reconhecer o símbolo de alternância.

sed versão 4.2.2 no Fedora 20.

É claro que eu dou aqui o problema muito genérico e básico.

O script real é muito complexo, com texto longo e análise crua.

Meu objetivo inicial foi imprimir o 4º elemento em cada agrupamento de massa de alternância. Agora devo dividir a partida, o que aumenta significativamente o código.

Alguém por favor pode reduzir minha confusão?

    
por mr.tee 01.05.2018 / 14:29

2 respostas

7

\x é expandido para o que é capturado no grupo de captura x th , os grupos de captura são numerados da esquerda para a direita com base na ocorrência da chave de abertura no regexp.

echo "abcd_aefghi" | sed -r "s/(a)(b)(c)(d)|(a)(e)(f)(g)//g;"
                               1  2  3  4   5  6  7  8

Esse regexp corresponde duas vezes. Uma vez em abcd (onde o grupo de captura 8 th não captura nada) e uma vez em aefg , onde o grupo de captura 8 th captura g . Portanto, abcd é substituído por nada e aefg com g e _ e hi são deixados intactos para que você obtenha _ghi como esperado.

Em:

sed -r "s/(a)(b)(c)(d)()|((a)(e)(f)(g))//g"
          1  2  3  4  5  67  8  9  10

Você obtém _ehi porque o grupo 8 th agora é o (e) um.

sed -r "s/(a)(b)(c)(d)()||||i am Not comment, Whats going here?|||||||((a)(e)(f)(g))//g"
          1  2  3  4  5                                               67  8  9  10

não é diferente. Exceto (embora isso não seja visível), por causa do || , haverá correspondências vazias entre h e i e uma extra no final (mais algumas com perl ).

redefinir números com base no operador de alternância não seria uma API muito útil. Se você deseja expandir para o que é correspondido pelo grupo de captura th em ambos os lados da alternação no seu exemplo, você sempre pode fazer:

sed -r 's/(a)(b)(c)(d)|(a)(e)(f)(g)//g'
          1  2  3  4   5  6  7  8

O que lhe daria o mesmo que perl ':

perl -lpe 's/(?|(a)(b)(c)(d)|(a)(e)(f)(g))//g'
                1  2  3  4   1  2  3  4

(onde poderia se expandir para o que (d) ou (g) capturou).

    
por 01.05.2018 / 15:16
0

Pelo que entendi, você não está feliz com a resposta dada, pois isso atrapalha seu código para o seu problema real. Difícil de ajudar você sem saber que problema real.

Para manter a quarta parte de cada alternação, você provavelmente deve fazer isso de maneira diferente:

sed -r 's/abcd|aefg/\n&/g;s/\n...//g'

marca cada partida com nova linha e remove a nova linha com os três caracteres indesejados em uma segunda passagem (isto é GNU- sed apenas, mas você pode fazer isso de forma semelhante para um% diferentesed).

Não há código ampliado com essa abordagem. Às vezes você só precisa fazer diferente. Claro que você também pode fazer isso com grupos em vez de apenas chars.

Mas se isso não resolver seu problema real (e você não souber como adaptá-lo), informe-nos seu problema real com dados de exemplo.

    
por 03.05.2018 / 13:51