tcl
Vanliga uttryck
Sök…
Syntax
- regexp? -omkopplare? exp sträng? matchVar? ? subMatchVar subMatchVar ...?
- regsub? -omkopplare? exp sträng subSpec? varName?
Anmärkningar
Detta ämne är inte avsett att diskutera regelbundna uttryck själva. Det finns många resurser på internet som förklarar vanliga uttryck och verktyg för att bygga regelbundna uttryck.
Detta ämne försöker täcka de vanliga switcharna och metoderna för att använda reguljära uttryck i Tcl och några av skillnaderna mellan Tcl och andra reguljära uttrycksmotorer.
Vanliga uttryck är i allmänhet långsamma. Den första frågan du bör ställa är "Behöver jag verkligen ett regelbundet uttryck?". Matcha bara vad du vill. Om du inte behöver andra data, matcha inte dem.
I dessa exempel på reguljära uttryck används omkopplaren-expanderad för att kunna kommentera och förklara det reguljära uttrycket.
Matchning
regexp kommandot används för att matcha ett regelbundet uttryck mot en sträng.
# 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]
regexp kommandot returnerar ett (sant) värde om en matchning gjordes eller 0 (falsk) om inte.
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"
}
För att matcha alla uttryck i vissa data använder du -all-omkopplaren och--linjen-omkopplaren för att returnera data. Observera att standarden är att behandla nyheter som alla andra data.
# 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
Newlinehantering
# 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 kräver ingen speciell hantering.
% set mydata {123ÂÃÄÈ456}
123ÂÃÄÈ456
% regexp {[[:alpha:]]+} $mydata match
1
% puts $match
ÂÃÄÈ
% regexp {\w+} $mydata match
1
% puts $match
123ÂÃÄÈ456
Dokumentation: regexp re_syntax
Blanda giriga och icke-giriga kvantifierare
Om du har en girig match som den första kvantifieraren, kommer hela RE att vara girig,
Om du har en icke-girig matchning som den första kvantifieraren, kommer hela RE att vara icke-girig.
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
I det första fallet är den första \ w + girig, så alla kvantifierare är markerade som giriga och. *? matchar mer än väntat.
I det andra fallet, det första. *? är icke-girig och alla kvantifierare markeras som icke-giriga.
Andra reguljära uttrycksmotorer kanske inte har problem med giriga / icke-giriga kvantifierare, men de är mycket långsammare.
Henry Spencer skrev : ... Problemet är att det är väldigt, väldigt svårt att skriva en generalisering av de uttalanden som täcker regelbundna uttryck för blandad girighet - en korrekt, implementeringsoberoende definition av vad reguljära uttryck för blandad girighet bör matcha - - och får dem att göra "vad folk förväntar sig". Jag har försökt. Jag försöker fortfarande. Ingen tur hittills. ...
Utbyte
regsub kommandot används för regelbunden uttrycksmatchning och substitution.
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.
Använda bakreferenser för referensmatchade data.
set mydata {The yellow dog has the blues.}
regsub {(yellow)} $mydata {"\1"} mydata
puts $mydata
The "yellow" dog has the blues.
Dokumentation: regsub re_syntax
Skillnader mellan Tcls RE-motor och andra RE-motorer.
- \ m: början av ett ord.
- \ M: Slutet på ett ord.
- \ y: Ordgräns.
- \ Y: en punkt som inte är en ordgräns.
- \ Z: matchar slutet på data.
Dokumentation: re_syntax
Matchning av en bokstavlig sträng med ett vanligt uttryck
Ibland måste du matcha en bokstavlig (sub-) sträng med ett regelbundet uttryck trots den substring som innehåller RE-metatecken. Även om ja, det är möjligt att skriva kod för att infoga lämpliga bakåtstreck för att göra det fungerar (med string map ) är det lättast att bara prefixera mönstret med ***= , vilket gör att RE-motorn behandlar resten av strängen som bara bokstavliga tecken , inaktivera alla ytterligare metatecken.
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!"
}
Observera att detta också betyder att du inte kan använda någon av förankringarna.