Que signifie \? signifie dans une expression régulière?

La command suivante est utilisée pour searchr un numéro de téléphone à 7 numbers:

grep "[[:digit:]]\{3\}[ -]\?[[:digit:]]\{4\}" file 

Que signifie \? représenter?

C'est comme ? dans de nombreux autres moteurs d'expression régulière, et signifie «correspondre à zéro ou un de tout ce qui l'a précédé».

Dans votre exemple, le \? est appliqué au [ -] , ce qui signifie qu'il essaie de faire correspondre un espace ou un less, mais que l'espace ou le less est facultatif.

Donc, l'un de ceux-ci correspondra:

 555 1234 555-1234 5551234 

La raison pour laquelle il est écrit comme \? plutôt que ? est pour la rétrocompatibilité.

La version originale de grep utilisait un type différent d'expression régulière appelée "expression régulière de base" où ? signifiait juste un point d'interrogation littéral.

Pour que GNU grep puisse avoir la fonctionnalité zéro ou une, ils l'ont ajouté, mais ont dû utiliser le \? syntaxe de sorte que les scripts qui ont utilisé ? toujours travaillé comme prévu.

Notez que grep a une option -E qui lui permet d'utiliser le type d'expression régulière le plus courant, appelé "expressions régulières étendues".

man 1 grep :

  -E, --extended-regexp Interpret PATTERN as an extended regular expression (ERE, see below). (-E is specified by POSIX.) -G, --basic-regexp Interpret PATTERN as a basic regular expression (BRE, see below). This is the default. 

 Repetition A regular expression may be followed by one of several repetition operators: ? The preceding item is optional and matched at most once. 

  grep understands three different versions of regular expression syntax: “basic,” “extended” and “perl.” 

 Basic vs Extended Regular Expressions In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \). 

Plus d'infos:

  • grep -E option et egrep
  • GNU grep – Basic vs Extended
  • Résumé de la syntaxe Regexp
  • Expression régulière – Wikipédia
  • Pourquoi certaines commands regex ont-elles des interprétations opposées de '\' avec différents caractères?

Malheureusement, la syntaxe exacte des expressions régulières varie légèrement entre les différents programmes: les regex grep ne sont pas exactement les mêmes que les regex sed, qui ne sont pas exactement les mêmes que les regex Emacs, qui ne sont pas exactement les mêmes que les regex C ++. sur. Pour aggraver les choses, même un outil "standard" comme grep peut varier légèrement entre les différents systèmes d'exploitation de type Unix.

Dans une regex, certains caractères ont une signification spéciale (comme les crochets dans votre exemple) et reviennent à leur signification normale en tant que caractères littéraux lorsque vous les «échappez» en leur faisant précéder d'une barre oblique inverse écrit comme \ [). D'autres fonctionnent dans l'autre sens, et ne prennent une signification particulière que lorsqu'elles sont échappées (par exemple, n n'est qu'une lettre, mais \ n est un saut de ligne). Et ceux-ci, encore une fois, peuvent varier entre les implémentations regex.

Dans la plupart des implémentations regex, un point d'interrogation signifie que l'élément précédent est optionnel, alors qu'un point d'interrogation échappé (\?) Est un point d'interrogation littéral. Mais dans quelques dialectes, c'est l'inverse. Votre exemple pourrait avoir un sens, mais je suppose que vous avez l'un des dialectes où? est un littéral et \? est le symbole optionnel. Donc, votre regex signifie probablement "trois numbers, éventuellement suivi d'un espace ou d'un tiret, suivi de quatre numbers".

(Un autre indice peut être vu dans les constructions comme \ {3 \}, ce qui est clairement destiné à signifier "exactement 3 de l'élément précédent". Dans la plupart des dialectes regex cela serait écrit {3}, et \ {serait un accolade littérale .)

Ceci est un résumé rapide des informations déjà contenues dans les autres réponses.

Dans grep correspond à un caractère de point d'interrogation littéral, et \? dénote zéro ou une occurrence de tout ce qui le précède. Donc dans l'exemple de votre question, [ -]\? correspond à un espace, ou un trait d'union, ou rien.

Dans egrep ou grep -E , c'est l'inverse; \? correspond à un point d'interrogation littéral, et ? dénote zéro ou une occurrence.

Cela s'applique à GNU grep; les détails pour les implémentations grep non-GNU peuvent différer légèrement. En particulier, grep et egrep étaient historiquement deux programmes distincts, et je ne pense pas que les anciens grep aient l'option -E . POSIX spécifie grep -E , mais (j'ai été surpris de le découvrir) ne mentionne pas egrep .