Bash = ~ regex e https://regex101.com/

1

Usando o link criei uma expressão regular para retornar a primeira ocorrência de um endereço IP em uma string.

RegExp:

(?:\d{1,3}\.)+(?:\d{1,3})

RegExp incluindo delimitadores:

/(?:\d{1,3}\.)+(?:\d{1,3})/

Com a seguinte string de teste:

eu-west                       140.243.64.99 

Ele retorna uma correspondência completa de:

140.243.64.99

Não importa o que eu tente com âncoras, etc, o seguinte script bash não funcionará com a expressão regular gerada.

temp="eu-west                       140.243.64.99            "
regexp="(?:\d{1,3}\.)+(?:\d{1,3})"
if [[ $temp =~ $regexp ]]; then
  echo "found a match"
else
  echo "No IP address returned"
fi
    
por rjm61 02.02.2018 / 16:19

3 respostas

3

\d é uma maneira não padronizada de dizer "qualquer dígito". Eu acho que vem do Perl, e muitas outras linguagens e utilitários suportam REs compatíveis com Perl (PCRE) também. (e, por exemplo, o GNU grep 2.27 no Debian stretch suporta os \w semelhantes para caracteres de palavras, mesmo no modo normal.)

O Bash não suporta \d , por isso, você precisa usar explicitamente [0-9] ou [[:digit:]] . O mesmo para o grupo que não captura (?:..) , use apenas (..) .

Isso deve imprimir match :

temp="eu-west                       140.243.64.99            "
regexp="([0-9]{1,3}\.)+([0-9]{1,3})"
[[ $temp =~ $regexp ]] && echo match
    
por 02.02.2018 / 16:28
2

(:...) e \d são operadores de expressões regulares perl ou PCRE (como no GNU grep -P ).

bash suporta apenas expressões regulares estendidas como em grep -E , exceto que para expressões regulares transmitidas literalmente como em [[ text =~ regexp-here ]] em oposição a como resultado de uma expansão sem aspas (como em [[ text =~ $var ]] ou [[ test =~ $(printf '%s\n' 'regexp-here') ]] ), limitado ao conjunto de recursos de expressão regular estendida POSIX.

Assim, mesmo em sistemas em que o grep -E '\d' funcionaria (os EREs do GNU já importaram algumas extensões de regexps perl como \s , então versões futuras também podem ter \d ), você teria que usar:

regexp='\d'
[[ $text =~ $regexp ]]

em bash para funcionar ( [[ $text =~ \d ]] não).

Para um shell que suporta PCREs, você pode usar zsh :

set -o rematchpcre
[[ $text =~ '(?:\d{1,3}\.)+(?:\d{1,3})' ]]

O ksh93 também suporta sua própria implementação de expressões regulares semelhantes a perl (não totalmente compatíveis) como parte de sua correspondência de padrões. Lá, você usaria:

regexp='~(P)(?:\d{1,3}\.)+(?:\d{1,3})'
[[ $text = $regexp ]]

(observe o = em vez de =~ . Você vai querer usar variáveis temporárias, pois é muito problemático quando você não o faz)

    
por 02.02.2018 / 17:07
0

O site regex101.com usa o PCRE (veja o canto superior esquerdo) como padrão e não tem suporte para regex "estendido" sintaxe. Isso é "Perl Compatible Regular Expresions", que vem (como é razoável esperar) do Perl.

O PCRE é suportado por algumas ferramentas (como grep -P ) sob algumas condições, mas o suporte ao regex bash dentro do [[…]] idiom é somente para regex estendido (como grep -E ).

Na regex estendida, o parêntese (?…) que não é de captura não existe e o \ d também está ausente. Você precisa usar simples (…) e [0-9] :

regexp="([0-9]{1,3}\.)+([0-9]{1,3})"
    
por 02.02.2018 / 19:37