web-dev-qa-db-fra.com

Différence entre '.' '?' et '*' dans les expressions régulières?

Pourrais-je avoir un exemple de la différence entre ces trois éléments (sont-ils des métacaractères?)?

Je sais que * signifie tout ou rien, mais je ne suis pas sûr que ce soit la bonne façon de penser. De même, . et ? semblent identiques. Ils correspondent à un personnage, non?

21
posixKing

Pris directement de Wikipedia :

? Le point d'interrogation indique zéro ou une occurrence de l'élément précédent. Par exemple, la couleur correspond à la fois à "couleur" et à "couleur".

* L'astérisque indique zéro ou plusieurs occurrences de l'élément précédent. Par exemple, ab * c correspond à "ac", "abc", "abbc", "abbbc", etc.

La grande différence est que l'astérisque correspond à zéro ou plusieurs occurrences , tandis que le point d'interrogation correspond à zéro ou une occurrence . Comparez ces deux exemples:

$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'                          
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'                          
colour
color
colouur

Parce que dans colouurla lettre u (l'élément précédent avant le qualificatif ?) s'est produite plusieurs fois, elle ne correspond pas à ?, mais elle correspond à *

Exemple similaire:

$ printf "error\neror\ner\n" | egrep 'er?or'                                   
eror
$ printf "error\neror\ner\n" | egrep 'er*or'                                   
error
eror

De la même page wikipedia:

Correspond à n'importe quel caractère (de nombreuses applications excluent les sauts de ligne et les caractères considérés comme nouveaux sont spécifiques à la saveur, au codage de caractères et à la plate-forme, mais il est prudent de supposer que le caractère de saut de ligne est inclus). Dans les expressions de crochet POSIX, le caractère de point correspond à un point littéral. Par exemple, a.c correspond à "abc", etc., mais [a.c] ne correspond qu'à "a", "." Ou "c".

Dans notre exemple,

$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'                           
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'                          
colouur

De manière appropriée, le dernier se lit comme suit: match any line that has "colou", plus any character, plus letter "r"

Conclusion

Vous avez demandé: "Je sais que" * "signifie tout ou rien, mais je ne suis pas sûr que ce soit la bonne façon de penser. De l'autre". " & '?' semble même. " Comme vous pouvez le constater, le point et l'astérisque ne sont pas exactement les mêmes. Le point agit sur n'importe quel caractère pouvant occuper cette position spécifique, tandis que le point d'interrogation agit sur l'élément précédent.

16

Vous confondez peut-être les expressions régulières avec les globes de shell

Dans la syntaxe d'expression régulière, . représente un caractère unique (en général, à l'exclusion du caractère de nouvelle ligne), tandis que * est un quantificateur signifiant zéro ou plusieurs des expressions rationnelles précédentes atom (caractère ou groupe). ? est un quantificateur signifiant zéro ou une instance de l’atome précédent, ou (dans les variantes de regex qui le prennent en charge) a modificateur qui définit le comportement du quantificateur comme non glouton.

Dans les globes de shell, ? représente un seul caractère (comme le . de la regex), tandis que * représente une séquence de zéro ou plusieurs caractères (équivalent à regex .*).

Quelques références qui pourraient vous être utiles sont http://www.regular-expressions.info/quickstart.html et http://mywiki.wooledge.org/glob

31
steeldriver

Remarque: Examples provided are in Python. Bien que le concept reste le même.

'.' est un symbole correspondant qui correspond à n’importe quel caractère, à l’exception de caractère de nouvelle ligne (cela peut aussi être remplacé par l’argument re.DOTALL en Python). Par conséquent, il est également appelé un caractère générique .

'*' est un quantificateur (définit la fréquence à laquelle un élément peut se produire). Est l'abréviation de {0,} .

Cela signifie "correspond à zéro ou plus" - le groupe qui précède l'étoile peut se produire n'importe quel nombre de fois dans le texte. Il peut être complètement absent ou répété encore et encore.

'?' est également un quantificateur . Est l'abréviation de {0,1} .

Cela signifie "Correspond à zéro ou à l'un des groupes précédant ce point d'interrogation." Il peut également être interprétée comme la partie précédant le point d'interrogation est facultative .

par exemple.:

pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'

mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'

Dans l'exemple ci-dessus '?' indique que les deux chiffres le précédant sont facultatifs. Ils peuvent ne pas apparaître ou apparaître au maximum une fois.

Différence entre '.' et '?':

'.' correspond/accepte/vérifie un seul caractère pour la place qu'il occupe dans l'expression régulière.

par exemple.:

pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']

'?' correspond/vérifie l'occurrence nulle ou unique du groupe le précédant .

Voir l'exemple de numéro de portable.

Même chose avec '*'. Il vérifiera zéro ou plusieurs occurrences du groupe le précédant .

Combinaison:

'.*': accepte autant de séquences que disponible. Approche gourmande .

'.*? 'Accepte la première séquence correspondante et s'arrête. Approche non-gourmande

Pour plus d'informations, lisez les deux questions suivantes ...

5
Dhaval Simaria