Patterns for text
A regular expression (a regex) is a small language for describing text: "one or more digits", "a word at the start of the line", "something that looks like an email address". xTalk uses the same regular expressions as Perl, Python and most other languages (PCRE), so what you learn here works almost everywhere.
| Pattern | Matches |
|---|---|
cat | the letters cat, anywhere |
. | any one character |
[aeiou], [0-9], [^,] | one character from a set, a range, or not in a set |
\d, \s, \w | a digit, a space or tab, a letter or digit or _ |
*, +, ? | after something: any number of it, one or more, none or one |
{3}, {2,4} | exactly 3 of it, from 2 to 4 |
^, $ | the start and the end of the text |
(...) | a group, which you can capture |
a|b | either a or b |
\., \$ | a character that means something, taken literally |
Is it there? matchText
matchText says whether a pattern is found anywhere in some text:
put matchText("Order 66 shipped", "[0-9]+")
put matchText("No numbers here", "[0-9]+")
put matchText("2024", "^\d{4}$")
put matchText("12024", "^\d{4}$")
true false true false
The last two show why ^ and $ matter: without them, "four digits" would be found inside a longer number.
Taking parts out: groups
Give matchText variables after the pattern, and each bracketed group's text is put into one of them, in order. This is how you pull a date, a price or a name out of a line:
put "Order 66 shipped on 2024-05-01" into tLine
if matchText(tLine, "(\d{4})-(\d{2})-(\d{2})", tYear, tMonth, tDay) then
put "Year" && tYear & ", month" && tMonth & ", day" && tDay
end if
get matchText("Ada Lovelace", "(\w+)\s+(\w+)", tFirst, tLast)
put tLast & "," && tFirst
Year 2024, month 05, day 01 Lovelace, Ada
Where is it? matchChunk
matchChunk is the same, but gives the positions of each group, the first and last character, so you can work on that chunk of the text. Here it finds every price in a line and adds them up:
put "price: $12.50, tax: $1.25, tip: $2" into tRest
put 0 into tTotal
repeat while matchChunk(tRest, "\$([0-9.]+)", tStart, tEnd)
add char tStart to tEnd of tRest to tTotal
delete char 1 to tEnd of tRest
end repeat
put tTotal
15.75
Replacing: replaceText
replaceText gives a copy of the text with every match of the pattern replaced. It is replace with patterns:
put replaceText("too many spaces", " +", " ")
put replaceText("Call 555-1234 or 555-9876", "\d{3}-\d{4}", "XXX-XXXX")
put replaceText("one,two;three four", "[,; ]", "|")
too many spaces Call XXX-XXXX or XXX-XXXX one|two|three|four
Ignoring case
Regular expressions care about capitals. Start the pattern with (?i) to make it ignore case:
put matchText("Hello", "^hello$")
put matchText("Hello", "(?i)^hello$")
false true
Checking input
A common use is checking that what someone typed has the right shape:
function looksLikeEmail pText
return matchText(pText, "^[^@\s]+@[^@\s]+\.[a-zA-Z]{2,}$")
end looksLikeEmail
function looksLikePostcode pText
return matchText(pText, "(?i)^[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}$")
end looksLikePostcode
put looksLikeEmail("ada@example.com")
put looksLikeEmail("not an email")
put looksLikePostcode("SW1A 1AA")
put looksLikePostcode("12345")
true false true false
put matchText("abc", "[a-z")
Try it yourself
From the log line 2026-11-05 21:30:07 ERROR disk full on /dev/sda1, pull out the time, the level and the message, and put them as [ERROR at 21:30:07] disk full on /dev/sda1.
Show a solution
put "2026-11-05 21:30:07 ERROR disk full on /dev/sda1" into tLine
if matchText(tLine, "^\S+ (\S+) (\w+) (.*)$", tTime, tLevel, tMessage) then
put "[" & tLevel && "at" && tTime & "]" && tMessage
end if
[ERROR at 21:30:07] disk full on /dev/sda1
Words in this lesson
Each one finds every lesson that uses it. The Dictionary has the whole story of each, with its syntax and more examples.