Regular Expressions Module 2
Characters, escapes and character classes interview questions
Interview questions on characters, escapes and character classes: warm-ups, then what each harder question tests and how a good answer starts.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher to mid
How many characters are special outside a character class in JavaScript, and what makes any one of them literal?
-
Fresher to mid
Why does one pattern need two backslashes in one place in your code and one in another?
Answered in the lesson Writing patterns in code: strings and escaping
-
Fresher to mid
What does a negated class such as [^0-9] match, and how is it different from the dot?
Answered in the lesson Character classes, ranges and negation
-
Fresher to mid
What do the three shorthand classes stand for, and why can one pattern match different characters in two languages?
Answered in the lesson Shorthand classes for digits, words and spaces
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Mid to senior
A log scanner uses /^log: .* done$/ to pick out single-line entries. Logs copied from a Windows file sometimes end with CRLF; copies from a web page sometimes carry a line separator (U+2028). Why does the pattern behave differently in Node.js and in Python here, and how do you write it so it behaves the same way everywhere?
- What it tests
- Knowing which code points each flavour keeps out of the dot, that only line feeds are kept out everywhere by default, and the portable idioms that cross lines.
- First step
- Name the four code points JavaScript keeps out of the dot (LF, CR, LS, PS) and the one Python, Go and PCRE2 keep out (LF alone). The scanner is single-line, so the pattern should reject every line terminator and the engines agree only on LF.
- Follow-ups
-
- How does /^log: .* done$/s change the behaviour on CRLF logs?
- What does
[^\n]*give you that.*does not? - If the same pattern must run in a shell command through grep, Python and a browser, how do you check that it matches the same text everywhere?
- The Windows log holds the line "log: ok \r done\n". Does /^log: .* done$/ match on each engine?
From the lesson Literals, metacharacters and the dot
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
You port a pattern for the Devanagari letter स (U+0938), written as \u0938 in Python, to PCRE2 in a PHP service, to Go and to JavaScript. Walk through which spellings each engine accepts, the one that silently changes meaning in JavaScript, and the one escape all four share for code points below 256.
- What it tests
- Knowing JavaScript's \u, \u{...} and Annex B, Python's \u/\U/\N{name}, PCRE2's \x{...} and \N{U+...} and Go's \x{...}, and the one shared escape \xhh.
- First step
- Say which spellings each flavour accepts, then show which one changes meaning silently in JavaScript without the u flag; close with \xhh as the one two-hex form all four flavours have.
- Follow-ups
-
- What writes U+0938 in PCRE2 and in Go?
- How does \u{938} without the u flag become 938 copies of a letter in JavaScript?
- Which code-point escape is the same in all four flavours, and how far does it reach?
- How would you match any Devanagari letter in each of the four engines?
From the lesson Literals, metacharacters and the dot
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
A ticket search box compiles whatever an agent types into a pattern. A JavaScript page and a Python service must report the same hits, and terms such as ERR-500 (timeout) or C++ arrive daily. How do you make the search sound, and how do you keep the two sides agreeing?
- What it tests
- Escaping user text with each engine own function, knowing that an unescaped term may match wrongly instead of failing, and not shipping escaped pattern text between flavours.
- First step
- Decide what the input is: text, not a pattern. Each side escapes it with its own function, RegExp.escape in the browser and re.escape in the service, and both compile the escaped text. Then reproduce the complaint with the exact term the agent used, because the symptom tells you which side escaped nothing.
- Follow-ups
-
- Why is sending the escaped string from the service to the page a bad idea?
- Which terms fail loudly, and which ones quietly return the wrong rows?
- What do you test so this cannot come back?
- What changes if agents are allowed to search with patterns on purpose?
From the lesson Writing patterns in code: strings and escaping
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to staff
A bulk editor lets an analyst type the text to find and the new text. Analysts report that a dollar amount disappeared from the new text in the Go worker and that the Python worker stopped with a bad escape error. Some analysts also want group references. How do you build it?
- What it tests
- Knowing that replacement text has its own escapes per flavour, that a pattern escaper must not be used on it, and how to offer group references without breaking plain text.
- First step
- Separate the two sides in the design: the text to find is escaped with the engine own function, and the new text goes in through a function replacement, which no flavour reads for dollar or backslash forms. That one change explains both reports, because each worker read the new text as instructions.
- Follow-ups
-
- Why did Go lose the amount while Python raised an error?
- How do you still offer group references to the analysts who want them?
- How would you show a preview that cannot lie?
- What would you log when a replacement changes nothing?
From the lesson Writing patterns in code: strings and escaping
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
A signup service in PHP checks usernames with preg_match('/^[[:alnum:]_-]+$/u', $name). Moved to Node.js as /^[[:alnum:]_-]+$/, it now rejects every username, with no error. Explain what JavaScript does with the pattern, and how you would port the check so both services accept the same names.
- What it tests
- Knowing that JavaScript has no POSIX names and reads the brackets as an ordinary class, spotting a silent failure, and porting a class by writing out the set the source flavour meant, Unicode included.
- First step
- Read the pattern as JavaScript does: the class ends at the first ], so [[:alnum:] is a set of seven characters, [ : a l n u m, and _-]+ is plain text after it. An anchored match then needs one of those seven, an underscore, a hyphen and one or more ], so AB-12 can never match.
- Follow-ups
-
- Why does adding the u flag help, even though the pattern still does not work?
- What does the /u modifier change about [[:alnum:]] in PHP, and how do you keep that in JavaScript?
- How would you catch a break like this before it reaches users?
From the lesson Character classes, ranges and negation
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Fresher to mid
A registration form checks names with ^[A-Za-zÀ-ÿ]+$, meant as "letters, accents allowed". Testers report that A×B is accepted, and that Łukasz and नेहा are rejected. Explain all three results and propose a class that does what the form meant.
- What it tests
- Reading a range as an interval of code points, knowing what the Latin-1 block holds, and choosing Unicode properties, with the marks a script needs, over hand-made ranges.
- First step
- Look up the two ends of the range: À is U+00C0 and ÿ is U+00FF, so the class takes all 64 code points between them, and two of those are not letters: × (U+00D7) and ÷ (U+00F7). Then look up Ł and the Devanagari letters, which lie far past U+00FF.
- Follow-ups
-
- Which Unicode-aware class would you use instead, and what does it still reject?
- Why does नेहा fail even with \p{L}+?
- Should a name field be checked with a character class at all?
From the lesson Character classes, ranges and negation
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A Python service checks a six-digit delivery code with re.fullmatch(r"\d{6}", code) and stores the string. A Go service that prints labels later refuses some stored codes with strconv.Atoi: invalid syntax, though every one passed the check. What went wrong, and how do you fix the check and the codes already stored?
- What it tests
- Knowing that \d in a Python str pattern is any Unicode decimal digit while Go reads only 0 to 9, deciding whether to refuse or convert such input, and repairing data a check let through.
- First step
- Take one refused code and print the code point of each character. If they are Devanagari, Tamil or other Nd digits, the Python check accepted them because \d is Unicode for str patterns, and Go refused them because its parser and its \d know only 0 to 9. Then settle the field's real rule: ASCII digits only, or any script converted to ASCII before it is stored.
- Follow-ups
-
- How do you convert digits of other scripts to 0 to 9 in Python?
- What else changes if you add re.ASCII to the pattern?
- How do you find and repair the codes already stored?
- Would storing int(code) have hidden the problem?
From the lesson Shorthand classes for digits, words and spaces
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
A sign-up form checks the display name with /^\w+(?: \w+)*$/u in the browser. Names written in Devanagari or Tamil, and names such as Zoë or O'Neil, are refused, while a_b and Asha3 are accepted. Why did the u flag not help, and what check would you write instead, in the browser and on a Python server?
- What it tests
- Knowing that JavaScript's \w is ASCII in every mode, building a name class from letters, marks and joiners, allowing the separators names need, and keeping the browser and server rules the same.
- First step
- Run the pattern on each refused name and note the first code point it stops at: ë, every Devanagari and Tamil letter and mark, the apostrophe. The u flag changes how code points are read, not what \w holds, which stays 63 ASCII characters, so the class itself has to change.
- Follow-ups
-
- Which separators should a name allow, and where?
- How do you keep the same rule on a Python server, whose re has no \p?
- Should the check limit the length, and in what unit?
- Why not drop the check altogether?
From the lesson Shorthand classes for digits, words and spaces
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
All Regular Expressions interview questions · The Regular Expressions track