Por que essa linha única do Perl Regex não torna o resultado completo em maiúsculas usando o \U
modificador?
Eu espero MY_NICE_WORD
.
$ perl -pe 's/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/\U$1_$2\E/g' <(echo 'myNiceWord HTTPHeader')
my_Nice_Word HTTP_Header
De acordo com os documentos,
The following escape sequences are available in constructs that interpolate, but not in transliterations.
\l lowercase next character only
\u titlecase (not uppercase!) next character only
\L lowercase all characters till \E or end of string
\U uppercase all characters till \E or end of string
\F foldcase all characters till \E or end of string
\Q quote (disable) pattern metacharacters till \E or
end of string
\E end either case modification or quoted section
(whichever was last seen)
fonte:man --pager 'less -p "The following escape sequences are available in constructs that interpolate, but not in transliterations."' perlop
O texto de substituição não está dentro do contexto de interpolação?
Exemplos de trabalho
Ao seguir a documentação, no meu entender, posso oferecer este exemplo prático:
$ perl -pe 's/(hello)/\U$1\E/g' <(echo hello)
HELLO
Expressão regular de https://stackoverflow.com/a/1176023/1236128
-> caso importante coberto por isto: HTTPHeader não se tornaria h_t_t_p_header, em vez disso HTTP_Header
(ou com HTTP_HEADER maiúsculo)
Você está usando asserções lookahead (
(?=…)
) e lookbehind ((<?=…)
) sem nada para corresponder e substituir.Acho que é isso que você está tentando alcançar, ou seja, introduzir um sublinhado na frente de cada letra maiúscula e depois colocar toda a string em maiúscula:
mas,
Então talvez
E se é aí que você está indo é mais fácil dividir a "palavra" em maiúsculas, juntar os componentes com
_
e colocar o resultado em maiúscula:Vejo dois problemas: você está usando asserções de largura zero. Não vejo nenhuma maneira de fazer isso em uma única passagem.
Isso funcionará para você:
Ele falha no myFWord.
Esta resposta aborda o problema do OP de tornar o resultado maiúsculo/não poder usar \U em capturas de grupo ao usar correspondências de largura 0 (e continuar usando a mesma expressão regular):
A resposta é que você não pode usar \U \E em
correspondências de grupo de largura zero(?<=...) ou (?=...) usando $1 e $2, porque eles não são grupos de captura, em vez disso, procure operadores (Obrigado Stéphane Chazelas)Uma solução alternativa para essa limitação sem alterar a expressão original é pós-processar o resultado da seguinte forma:
Use a variável especial Perl
$_
para processar a saída da expressão aplicada a uma string:$_ = uc($_)
em queuc
é uma função incorporada em maiúsculas em Perl, convertendo o resultado em maiúsculas.PS: o comentário de muru respondeu à pergunta de por que \U não funciona, que foi a motivação para minha linha de pensamento nesta resposta. Obrigado.