tcl
Wyrażenia regularne
Szukaj…
Składnia
- regexp? przełączniki? exp ciąg? matchVar? ? subMatchVar subMatchVar ...?
- regsub? przełączniki? exp ciąg subSpec? varName?
Uwagi
Ten temat nie jest przeznaczony do omawiania samych wyrażeń regularnych. W Internecie znajduje się wiele zasobów wyjaśniających wyrażenia regularne i narzędzia ułatwiające tworzenie wyrażeń regularnych.
W tym temacie postaramy się omówić typowe przełączniki i metody używania wyrażeń regularnych w Tcl oraz niektóre różnice między Tcl i innymi silnikami wyrażeń regularnych.
Wyrażenia regularne są na ogół wolne. Pierwsze pytanie, które powinieneś zadać to „Czy naprawdę potrzebuję wyrażenia regularnego?”. Dopasuj tylko to, co chcesz. Jeśli nie potrzebujesz innych danych, nie dopasowuj ich.
Do celów tych przykładów wyrażeń regularnych użyty zostanie przełącznik -rozwinięty, aby móc komentować i wyjaśniać wyrażenie regularne.
Pasujący
Polecenie regexp służy do dopasowania wyrażenia regularnego do łańcucha.
# This is a very simplistic e-mail matcher.
# e-mail addresses are extremely complicated to match properly.
# there is no guarantee that this regex will properly match e-mail addresses.
set mydata "send mail to [email protected] please"
regexp -expanded {
\y # word boundary
[^@\s]+ # characters that are not an @ or a space character
@ # a single @ sign
[\w.-]+ # normal characters and dots and dash
\. # a dot character
\w+ # normal characters.
\y # word boundary
} $mydata emailaddr
puts $emailaddr
[email protected]
Polecenie regexp zwróci wartość 1 (prawda), jeśli dopasowanie zostało wykonane, lub 0 (fałsz), jeśli nie.
set mydata "hello wrld, this is Tcl"
# faster would be to use: [string match *world* $mydata]
if { [regexp {world} $mydata] } {
puts "spelling correct"
} else {
puts "typographical error"
}
Aby dopasować wszystkie wyrażenia w niektórych danych, użyj przełącznika -all i przełącznika -inline, aby zwrócić dane. Zauważ, że domyślnie traktowane są nowe wiersze jak inne dane.
# simplistic english ordinal word matcher.
set mydata {
This is the first line.
This is the second line.
This is the third line.
This is the fourth line.
}
set mymatches [regexp -all -inline -expanded {
\y # word boundary
\w+ # standard characters
(?:st|nd|rd|th) # ending in st, nd, rd or th
# The ?: operator is used here as we don't
# want to return the match specified inside
# the grouping () operator.
\y # word boundary
} $mydata]
puts $mymatches
first second third fourth
# if the ?: operator was not used, the data returned would be:
first st second nd third rd fourth th
Obsługa nowej linii
# find real numbers at the end of a line (fake data).
set mydata {
White 0.87 percent saturation.
Specular reflection: 0.995
Blue 0.56 percent saturation.
Specular reflection: 0.421
}
# the -line switch will enable newline matching.
# without -line, the $ would match the end of the data.
set mymatches [regexp -line -all -inline -expanded {
\y # word boundary
\d\.\d+ # a real number
$ # at the end of a line.
} $mydata]
puts $mymatches
0.995 0.421
Unicode nie wymaga specjalnej obsługi.
% set mydata {123ÂÃÄÈ456}
123ÂÃÄÈ456
% regexp {[[:alpha:]]+} $mydata match
1
% puts $match
ÂÃÄÈ
% regexp {\w+} $mydata match
1
% puts $match
123ÂÃÄÈ456
Dokumentacja: regexp re_syntax
Mieszanie kwantyfikatorów chciwych i niechcianych
Jeśli masz zachłanne dopasowanie jako pierwszy kwantyfikator, całe RE będzie zachłanne,
Jeśli jako pierwszy kwantyfikator masz dopasowanie inne niż chciwe, całe RE nie będzie zachłanne.
set mydata {
Device widget1: port: 156 alias: input2
Device widget2: alias: input1
Device widget3: port: 238 alias: processor2
Device widget4: alias: output2
}
regexp {Device\s(\w+):\s(.*?)alias} $mydata alldata devname devdata
puts "$devname $devdata"
widget1 port: 156 alias: input2
regexp {Device\s(.*?):\s(.*?)alias} $mydata alldata devname devdata
puts "$devname $devdata"
widget1 port: 156
W pierwszym przypadku pierwszy \ w + jest zachłanny, więc wszystkie kwantyfikatory są oznaczone jako zachłanne, a. *? dopasowuje więcej niż oczekiwano.
W drugim przypadku pierwszy. *? nie jest chciwy, a wszystkie kwantyfikatory są oznaczone jako nie chciwe.
Inne silniki wyrażeń regularnych mogą nie mieć problemu z kwantyfikatorami chciwymi / niechcianymi, ale są znacznie wolniejsze.
Henry Spencer napisał : ... Problem polega na tym, że bardzo, bardzo trudno jest napisać uogólnienie tych stwierdzeń, które obejmuje wyrażenia regularne o mieszanej chciwości - prawidłowa, niezależna od implementacji definicja tego, co wyrażenia regularne o mieszanej chciwości powinny pasować - - i sprawia, że robią „to, czego oczekują ludzie”. Próbowałem. Nadal próbuję. Jak dotąd brak szczęścia. ...
Podstawienie
Polecenie regsub służy do dopasowywania i podstawiania wyrażeń regularnych.
set mydata {The yellow dog has the blues.}
# create a new string; only the first match is replaced.
set newdata [regsub {(yellow|blue)} $mydata green]
puts $newdata
The green dog has the blues.
# replace the data in the same string; all matches are replaced
regsub -all {(yellow|blue)} $mydata red mydata
puts $mydata
The red dog has the reds.
# another way to create a new string
regsub {(yellow|blue)} $mydata red mynewdata
puts $mynewdata
The red dog has the blues.
Korzystanie z referencji wstecznych do referencyjnych dopasowanych danych.
set mydata {The yellow dog has the blues.}
regsub {(yellow)} $mydata {"\1"} mydata
puts $mydata
The "yellow" dog has the blues.
Dokumentacja: regsub re_syntax
Różnice między silnikiem RE Tcl a innymi silnikami RE.
- \ m: początek słowa.
- \ M: Koniec słowa.
- \ y: granica słowa.
- \ Y: punkt, który nie jest granicą słowa.
- \ Z: dopasowuje koniec danych.
Dokumentacja: re_syntax
Dopasowywanie dosłownego łańcucha z wyrażeniem regularnym
Czasami musisz dopasować dosłowny (pod-) ciąg znaków z wyrażeniem regularnym pomimo tego podłańcucha zawierającego metaznaki RE. Chociaż tak, można napisać kod, aby wstawić odpowiednie ukośniki odwrotne, aby to zadziałało (przy użyciu string map ), najłatwiej jest po prostu poprzedzić wzorzec znakiem ***= , co powoduje, że silnik RE traktuje resztę ciągu jako tylko literalne znaki , wyłączając wszystkie dalsze metaznaki.
set sampleText "This is some text with \[brackets\] in it."
set searchFor {[brackets]}
if {[ regexp ***=$searchFor $sampleText ]} {
# This message will be printed
puts "Found it!"
}
Pamiętaj, że oznacza to również, że nie możesz użyć żadnej z kotwic.