Unterschied zwischen '.' , '?' und '*' in regulären Ausdrücken?

21

Könnte ich ein Beispiel dafür bekommen, wie sich diese drei Elemente (heißen sie Metazeichen?) Unterscheiden?

Ich weiß, dass *das alles oder nichts bedeutet, aber ich bin nicht sicher, ob es der richtige Weg ist, darüber nachzudenken. Auf der anderen Seite .und ?scheinen gleich. Sie stimmen mit einem Charakter überein, oder?

posixKing
quelle

Antworten:

16

Direkt aus Wikipedia entnommen :

? Das Fragezeichen gibt null oder ein Vorkommen des vorhergehenden Elements an. Beispielsweise stimmt Farbe sowohl mit "Farbe" als auch mit "Farbe" überein.

*Das Sternchen zeigt null oder mehr Vorkommen des vorhergehenden Elements an. Beispielsweise stimmt ab * c mit "ac", "abc", "abbc", "abbbc" usw. überein.

Der große Unterschied besteht darin, dass das Sternchen mit null oder mehr Vorkommen übereinstimmt, während das Fragezeichen mit null oder einem Vorkommen übereinstimmt . Vergleichen Sie diese beiden Beispiele:

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

Da in colouurdem Buchstaben u (dem vorherigen Element vor dem Qualifikationsmerkmal ?) mehrmals vorgekommen ?ist, stimmt das nicht mit überein , aber es stimmt mit überein*

Ähnliches Beispiel:

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

Von der gleichen Wikipedia-Seite:

Stimmt mit jedem einzelnen Zeichen überein (viele Anwendungen schließen Zeilenumbrüche aus und genau die Zeichen, die als Zeilenumbrüche gelten, sind geschmacks-, zeichencodierungs- und plattformspezifisch, es kann jedoch davon ausgegangen werden, dass das Zeilenvorschubzeichen enthalten ist). In POSIX-Klammerausdrücken entspricht das Punktzeichen einem Literalpunkt. Zum Beispiel stimmt ac mit "abc" usw. überein, aber [ac] stimmt nur mit "a", "." Oder "c" überein.

In unserem Beispiel

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

Passenderweise lautet der letzte als match any line that has "colou", plus any character, plus letter "r"

Fazit

Sie haben gefragt: "Ich weiß, dass '*' alles oder nichts bedeutet, aber ich bin mir nicht sicher, ob es der richtige Weg ist, darüber nachzudenken. Auf der anderen Seite". & '?' scheinen gleich. " Wie Sie sehen, sind der Punkt und der Stern nicht genau gleich. Der Punkt wirkt auf jedes Zeichen, das diese bestimmte Position einnimmt, während das Fragezeichen auf das vorhergehende Element wirkt.

Sergiy Kolodyazhnyy
quelle
32

Möglicherweise verwechseln Sie reguläre Ausdrücke mit Shell-Globs

In regulären Ausdrücken steht die Syntax .für ein einzelnes Zeichen (normalerweise ohne das Newline-Zeichen), während sie *ein Quantifizierer ist , der null oder mehr des vorhergehenden Regex-Atoms (Zeichen oder Gruppe) bedeutet. ?ist ein Quantifizierer, der null oder eine Instanz des vorhergehenden Atoms bedeutet, oder (in Regex-Varianten, die dies unterstützen) ein Modifizierer , der das Quantifiziererverhalten auf nicht gierig setzt.

Stellt in Shell-Globs ?ein einzelnes Zeichen (wie die Regex .) dar, während *eine Folge von null oder mehr Zeichen (entspricht Regex .*) dargestellt wird.

Einige nützliche Referenzen sind http://www.regular-expressions.info/quickstart.html und http://mywiki.wooledge.org/glob

Stahlfahrer
quelle
6

Hinweis: Das Examples provided are in Python.Konzept bleibt jedoch dasselbe.

'.'ist ein übereinstimmendes Symbol, das mit jedem Zeichen außer dem Zeilenumbruchzeichen übereinstimmt (dies kann auch mit re.DOTALLArgumenten in Python überschrieben werden ). Daher wird es auch als Wildcard bezeichnet .

'*' ist ein Quantifizierer (definiert, wie oft ein Element vorkommen kann). Ist die Abkürzung für {0,} .

Es bedeutet "Keine oder mehr Treffer" - die Gruppe vor dem Stern kann beliebig oft im Text vorkommen. Es kann ganz fehlen oder immer wieder wiederholt werden.

'?'ist auch ein Quantifizierer . Ist die Abkürzung für {0,1} .

Es bedeutet "Keine Übereinstimmung mit oder eine Übereinstimmung mit der Gruppe vor diesem Fragezeichen".Es kann auch so interpretiert werden, dass der Teil vor dem Fragezeichen optional ist .

z.B:

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'

Im obigen Beispiel '?' Gibt an, dass die beiden vorangestellten Ziffern optional sind. Sie dürfen nicht oder höchstens einmal vorkommen.

Unterschied zwischen '.' und '?':

'.' passt / akzeptiert / überprüft einem einzelnen Zeichen für die Stelle, an der es sich im regulären Ausdruck befindet.

z.B:

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

'?'Stimmt mit dem Null- oder Einzelvorkommen der Gruppe überein oder überprüft es .

Überprüfen Sie das Beispiel für eine Mobiltelefonnummer.

Gleiches gilt für '*'. Es werden null oder mehr Vorkommen der vorhergehenden Gruppe überprüft .

Kombination:

'.*': Akzeptiert so viele Sequenzen wie verfügbar. Gieriger Ansatz .

'.*?'Akzeptiert die erste übereinstimmende Sequenz und stoppt. Nicht gieriger Ansatz

Weitere Informationen finden Sie in den folgenden zwei Fragen ...

Dhaval Simaria
quelle