Notes › Tech Notes › 13 Digits In, 11 Out: the Regex Boundaries of the Seven Built-in Types in text-extract

13 Digits In, 11 Out: the Regex Boundaries of the Seven Built-in Types in text-extract

Measured boundaries of the seven built-in text-extract patterns: the phone tier takes any 11 digits, the URL tier needs a protocol header and keeps a trailing parenthesis, IPv4 rejects out-of-range and leading-zero segments, and the number tier splits 1,234.50 into 2 lines.

The pasted number lost two digits

Paste 13 digits run together, 1381234567890, and the result box returns only the 11-digit 13812345678; paste 21 digits the same way and it is still 1 line. The digits that fall off raise no error and no warning. Nothing marks the gap on screen, so the only way to catch it is to count the digits yourself.

This is the default tier of Text Information Extraction. The template measures 6033 bytes over 149 lines, and the seven patterns in RULES are 11, 46, 25, 83, 75, 15 and 9 characters long. All seven carry only the g flag, and only the IP tier, the 83-character one, has a boundary assertion. Each length in the table below is the pattern exactly as written in the template, not the length of what it matches, and the table gives every tier as measured.

TypePattern length in charactersMeasured hitMeasured zero hits
phone11联系电话13812345678请查收138-0013-8000
email46a..b@example.comtest@example.c
URL link25http://localhost:8080/appftp://example.com/file
IP address83255.255.255.255192.168.001.1
ID card number75a string of 18 charactersa string of 17 characters
number153.14 and -3.14full-width 123
English word9hello world gives 2 itemsa line of only Chinese gives 0 items

Phone tier: 11 digits is enough, it never asks where they came from

In 联系电话13812345678请查收 the digits sit right against Chinese characters with no separator on either side, and the tier still returns 1 hit. The middle of the 18-digit run in the preset sample yields 19900101123, and from +8613800138000 the match is the last 11 digits with the prefix left outside the result. The separator is what breaks the chain: 138-0013-8000 and 138 0013 8000 both return 0 hits, and so do 11 full-width digits. This tier reads digit shapes alone and never looks at what stands next to them.

No boundary assertion: keep 11 digits, the rest forms no line 13 digits run together Keeps 11, drops 2 21 digits run together still only 1 line With a separator 0 hits The green band is the 11 kept digits

Figure 1: what the phone tier returns for three kinds of input

Email tier: wider than the syntax, stricter at the tail

The 46-character pattern accepts a plus alias, a percent sign, two dots in a row and the whole string in capitals, so a..b@example.com and u@-example.com both match end to end. It is strict at the end: the quantifier on the suffix part is {2,}, so test@example and the single-letter suffix test@example.c return 0 hits.

URL tier: the protocol header is a hard gate, the tail is luck

The 25-character pattern hard-codes the protocol header, so example.com, www.example.com and ftp://example.com/file all return 0 hits, while port and query string go unchecked. Inside the excluded character class the full-width right parenthesis U+FF09 is written twice in the same class, yet the ASCII parenthesis and the ASCII semicolon are not in it at all. So what (https://example.com/y) gives back is https://example.com/y), with a right parenthesis still hanging on the tail. That tail is not trimmed afterwards, it belongs to the returned value.

IP tier: the only one of the seven with a boundary assertion

The 83-character pattern guards both ends. 0.0.0.0, 255.255.255.255 and 192.168.1.1 each give 1 hit. Out-of-range segments get no mercy: 999.1.1.1 and 256.1.1.1 give 0 hits, and so does the three-segment 1.2.3. One leading zero in any segment kills the whole string, so 01.2.3.4 and 192.168.001.1 yield no partial result either. The character in front blocks it too: inside ID12192.168.1.1 the legal address cannot anchor because of the assertion, again 0 hits.

Number tier: commas split, hyphens turn into minus signs

The 15-character pattern does no numeric conversion, so 007 and a 30-digit run are kept character by character. But it reads the comma as a separator: 1,234.50 comes out as 2 lines ["1","234.50"], one amount split in two; 2026-11-05 is worse, 3 lines ["2026","-11","-05"], every hyphen read as a minus sign, adding two negative numbers that were never there. One amount can therefore occupy two lines without a single character being lost.

English word tier: it cuts runs of letters, not words

The 9-character pattern grabs runs of consecutive ASCII letters. https://www.example.com/path yields 5 items, including the protocol name and com; café naïve is cut into 3 fragments; a line of only Chinese gives 0 items. With dedup on there is also a path that swallows words: that 60-character line of prototype-chain method names gives 6 items with dedup off and 2 with it on, because toString, valueOf, hasOwnProperty and constructor count as already seen and are dropped. There is no dictionary behind this tier, the cut is made purely by which characters count as letters.

Pasting 50 lines at once: the line count equals the hit count

Paste a mixed sample of 50 lines and 1487 characters in one go: the seven types return 265 hits in total and 160 after dedup, 105 fewer. By tier, number goes from 93 items to 64, word from 133 to 67, url from 11 to 11, and those 11 are all different, so dedup did work. The output line count always equals the hit count; the measured values do not end in a newline, and empty or non-matching lines contribute 0 lines. Dedup keeps the position of the first occurrence and does not sort lexicographically. Time was measured only on the Node side: 200 runs of the phone tier on this sample add up to 8.5 ms, an average of 0.0427 ms each; writing 20000 phone numbers into one 220000-character line returns 20000 items in 1.9 ms. Neither value includes browser parsing or repainting, and browser-side timing was not measured.

Same 50-line sample: dark dedup off, light dedup on phone 10 to 5 email 8 to 7 url 11 to 11 ip 10 to 6 number 93 to 64 word 133 to 67

Figure 2: counts before and after dedup on six tiers of that sample

It reports no error and never says what is missing

The page has no string such as 「未找到」 for nothing found. With 0 hits but a non-empty input, the statistics line still reads 「匹配数量:0」 and the total text length stays the length of the input; switch across the 7 tiers and it is unchanged 7 times. When the input is empty once whitespace is stripped, all three outlets clear at once, the result box, the highlight area and the statistics area, and even the 「匹配数量:0」 line is gone, leaving only the placeholder the template writes, 「提取结果...」. For the ID card number exactly two things are on record: it sits at position 5 in the type list, and a matched string is always 18 characters. Nothing about the content itself was tested. The statistics keep describing the input even when nothing in it matched.

Highlighting and extraction are not the same match

HTTP://EXAMPLE.COM/PATH extracts 0 items in the URL tier and the statistics also write 0, yet with highlighting on for that same input, 1 region was measured wrapping all 23 characters. The result box is empty, and the two matches run on different rules. All seven patterns here run once inside this page, so they never reach the case of reusing one pattern repeatedly in your own code; the older article regex flags and state covers that case.

FAQ

Q: Two numbers on one line, why only one line out?

Check whether they run together: two different numbers joined into 22 digits split as 11 plus 11, while 13 digits or 21 digits give only 1 line, because after 11 digits are taken the rest cannot form another match. It does not look back into the overlap.

Q: The result is shorter than the source, did it eat characters?

Not necessarily. The email tier needs a suffix of at least 2 letters, so a missing suffix and a single-letter suffix both miss; the URL tier returns 0 items with no protocol header; the number tier splits an amount with a thousands comma into 2 lines, it does not swallow anything.

Q: Why does turning on dedup cut the count so much?

On the 50-line sample the seven types fall from 265 items to 160, and the word tier alone accounts for 66. Dedup only governs the result list: with 2 output lines the highlight area can still be 3 regions. How to collapse repeats under a business rule is recorded in batch information extraction.

📎 Related articles

120 word slots, 15 whole sentences and 1 hard-coded opening: auditing the lorem-ipsum word list and measuring repeated fragments 2026-11-05 SVG preview sizes: the box equals the container, and r=1 measures 2 pixels once viewBox is removed 2026-11-05 Empty Fields Survive the Text Column Split: a,,b Stays, an Index Out of Range Fills Blank and 0 or abc Returns Every Column 2026-11-05 How a 1 GB File Is Built From 1024 Chunks: Chunk Rhythm, Cancel Boundaries and Three Fill Bytes in a File Generator 2026-11-04 Three Edges of Filename Extraction: The Trailing Slash Backstops One Step, the Query String Stays Whole, Blank Lines Vanish Silently 2026-11-04