En utilisant https://regex101.com/, j'ai construit une expression régulière pour renvoyer la première occurrence d'une adresse IP dans une chaîne.
RegExp:
(?:\d{1,3}\.)+(?:\d{1,3})
RegExp, y compris les délimiteurs:
/(?:\d{1,3}\.)+(?:\d{1,3})/
Avec la chaîne de test suivante:
eu-west 140.243.64.99
Il renvoie une correspondance complète de:
140.243.64.99
Peu importe ce que j'essaie avec des ancres, etc., le script bash suivant ne fonctionnera pas avec l'expression régulière générée.
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
bash
regular-expression
rjm61
la source
la source
=~
opérateur est décrit ici dans le manuel où il est écrit bash utilise des "expressions régulières étendues". Les expressions rationnelles étendues sont décrites dans laregex(7)
page de manuel et brièvement résumées ici .Réponses:
\d
est une façon non standard de dire "n'importe quel chiffre". Je pense que cela vient de Perl, et beaucoup d'autres langages et utilitaires prennent également en charge les RE compatibles avec Perl (PCRE). (et par exemple GNU grep 2.27 dans Debian Stretch prend en charge le même\w
pour les caractères de mots même en mode normal.)Bash ne prend pas en charge
\d
, cependant, vous devez donc utiliser explicitement[0-9]
ou[[:digit:]]
. Idem pour le groupe non capturant(?:..)
, utilisez juste à la(..)
place.Cela devrait imprimer
match
:la source
grep
charge\d
sans-P
?\w
et\b
, ce que j'ai appris de Perl, je suis donc confus.\d
ou le PCRE est "non standard". Ils sont assez standard, juste un standard différent des expressions régulières originales et des expressions régulières étendues.\d
. Bien que vous ayez raison, les PCRE sont plutôt standard ou les moins bien définis. La question ennuyeux est que GNU grep (ou glibc) prend en charge certains PCRE comme des atomes, au moins\w
et\s
l'interprétation ERE, et dans ce contexte , ils très bien sont non standard. Ma formulation pourrait bien provenir en partie de cela et du mauvais souvenir qui\d
était également supporté par GNU.(:...)
et\d
sont des opérateurs d'expressions régulières perl ou PCRE (comme dans GNUgrep -P
).bash
prend uniquement en charge les expressions régulières étendues comme dansgrep -E
sauf que pour les expressions rationnelles passées littéralement comme dans[[ text =~ regexp-here ]]
et non comme le résultat d'une expansion non citée (comme dans[[ text =~ $var ]]
ou[[ test =~ $(printf '%s\n' 'regexp-here') ]]
), elle est limitée à l'ensemble de fonctionnalités d'expressions régulières étendues POSIX.Donc, même sur les systèmes où
grep -E '\d'
cela fonctionnerait (les ERE GNU ont déjà importé certaines extensions à partir d'expressions régulières perl comme\s
les futures versions pourraient également le faire\d
), vous devez utiliser:dans
bash
pour que cela fonctionne ([[ $text =~ \d ]]
ne serait pas).Pour un shell qui prend en charge les PCRE, vous pouvez utiliser à la
zsh
place:ksh93 prend également en charge sa propre implémentation d'expressions régulières de type perl (pas entièrement compatibles) dans le cadre de sa correspondance de modèle. Là, vous utiliseriez:
(notez le
=
au lieu de=~
. Vous voudrez utiliser des variables temporaires car il est très bogué quand vous ne le faites pas)la source
Le site regex101.com utilise PCRE (regardez dans le coin supérieur gauche) par défaut, et il ne prend pas en charge la syntaxe regex "étendue". Il s'agit des "expressions régulières compatibles Perl", qui viennent (comme on peut raisonnablement s'y attendre) de Perl.
PCRE est pris en charge par certains outils (comme
grep -P
) dans certaines conditions, mais la prise en charge des expressions rationnelles bash à l'intérieur de l'[[…]]
idiome est uniquement pour l'expression régulière étendue (commegrep -E
).Dans l'expression régulière étendue, la
(?…)
parenthèse de non-capture n'existe pas et le \ d est également manquant. Vous devez utiliser simple(…)
et[0-9]
:la source