正则表达式速查表 — 每个语法元素都有示例
每个正则表达式语法元素都附可运行的示例,标明在 JavaScript、PCRE/PHP、Python、Go、Java 和 .NET 中的支持情况,并提供一键在正则测试工具中试用的链接。
最后核对:2026-10-18 依据ECMAScript 2025(MDN)、PCRE2 10.45、Python 3.14 re、Go 1.27 regexp/syntax、Java 25 Pattern 以及 .NET 正则表达式参考文档核对。来源:MDN regular expressions, PCRE2 pattern syntax, Python re, Go regexp/syntax, Java Pattern, .NET regex quick reference。
字符与转义
大多数字符匹配其自身。以下十二个字符有特殊含义,要按字面匹配时需加反斜杠:\ ^ $ . | ? * + ( ) [ {(在某些位置,] 和 } 也需要)。
.任意字符除换行符外的任意单个字符。加上 s(dotAll)标志后也匹配换行符。
/h.t/g
目标文本 “hat hot h t hit h↵t”
匹配 “hat” “hot” “h t” “hit”- Python re: 只排除 \n;JavaScript 还会排除 \r、\u2028 和 \u2029。
- Go RE2: 只排除 \n。
\. \$ \(转义元字符反斜杠让紧随其后的特殊字符按字面匹配:\. 是真正的点,\$ 是美元符号。
/\$\d+\.\d{2}/g
目标文本 “Total $45.00, tax $3.15, tip 5”
匹配 “$45.00” “$3.15”\t \n \r制表符、换行符、回车符用名称表示控制字符。Windows 的换行是 \r\n;\r?\n 两种风格都能匹配。
/\w+\t\w+/g
目标文本 “name⇥age↵ana⇥31”
匹配 “name⇥age” “ana⇥31”\xhh按十六进制码表示字符正好两位十六进制数:\x41 是 A,\x20 是空格。
/\x41/g
目标文本 “A b A”
匹配 “A” “A”\uhhhh按 Unicode 码元表示字符四位十六进制数,用于基本多文种平面中的字符:\u00e9 是 é。
/\u00e9/g
目标文本 “café résumé”
匹配 “é” “é” “é”- PCRE / PHP: 使用 \x{e9}。
- Go RE2: 使用 \x{e9}。
\u{1F600}任意码位(含辅助平面)带花括号的码位写法,emoji 等 U+FFFF 以上的字符需要用它。JavaScript 中需要 u 或 v 标志。
/\u{1F600}/gu
目标文本 “Hi 😀 there 😀”
匹配 “😀” “😀”- PCRE / PHP: 写作 \x{1F600}(PHP 需要 u 修饰符)。
- Python re: 写作 \U0001F600(八位十六进制数)。
- Go RE2: 写作 \x{1F600}。
- Java: 写作 \x{1F600}。
- .NET: 只支持 \uhhhh;一个 emoji 是两个 UTF-16 码元,例如 \uD83D\uDE00。
字符类
字符类只匹配集合中的一个字符。在 [ ] 内,大多数元字符失去特殊含义;只有 ] \ ^ 和 - 需要注意。
[abc]其中任意一个列表中的一个字符。
/gr[ae]y/g
目标文本 “gray grey groy”
匹配 “gray” “grey”[^abc]不属于其中任何一个不在列表中的一个字符(^ 不在开头时按字面匹配)。也会匹配换行符。
/[^aeiou\s]/g
目标文本 “regex”
匹配 “r” “g” “x”[a-z]范围两个码位之间的字符。可以组合多个范围:[A-Fa-f0-9] 表示一个十六进制数字。放在开头或末尾的 - 按字面匹配。
/[A-Fa-f0-9]+/g
目标文本 “x: 3fA9 zz”
匹配 “3fA9”\d \D数字 / 非数字\d 是数字,\D 是其他任意字符。
/\d+/g
目标文本 “Order 66, room 101”
匹配 “66” “101”- Python re: 在 str 模式中 \d 匹配任何 Unicode 数字(如 ٣);只想匹配 0-9 请用 re.ASCII。
- .NET: 匹配任何 Unicode 数字,除非设置了 RegexOptions.ECMAScript。
\w \W单词字符 / 非单词字符字母、数字和下划线。在 JavaScript 和 Go 中仅限 ASCII:\w 不匹配 é。
/\w+/g
目标文本 “snake_case and kebab-case”
匹配 “snake_case” “and” “kebab” “case”- PCRE / PHP: 仅 ASCII,除非使用 PCRE2_UCP(PHP:u 修饰符加 (*UCP))。
- Python re: 在 str 模式中默认匹配 Unicode 字母和数字。
- Java: 仅 ASCII,除非开启 U 标志(UNICODE_CHARACTER_CLASS)。
- .NET: Unicode 字母、数字和连接符标点。
\s \S空白 / 非空白空格、制表符、换行符以及(在大多数引擎中)其他 Unicode 空白字符。
/\s+/g
目标文本 “a b⇥c”
匹配 “ ” “⇥”- Go RE2: 仅 ASCII 空白:\t \n \f \r 和空格。
[[:alpha:]]POSIX 方括号字符类命名字符类,如 [:alpha:]、[:digit:]、[:space:]、[:punct:],写在方括号内使用。
[[:alpha:]]+- JavaScript: 使用 [A-Za-z],或加 u 标志使用 \p{L}。
- Java: 使用 \p{Alpha}、\p{Digit}、\p{Punct}。
[\p{L}--[a-z]]字符类差集 / 交集字符类内部的集合运算。JavaScript 需要 v 标志(ES2024):-- 表示差集,&& 表示交集。
/[\p{L}--[a-z]]+/gv
目标文本 “abcÉtéXYZ”
匹配 “É” “éXYZ”- PCRE / PHP: 仅 PCRE2 10.45+,使用 (?[ … ]) 扩展字符类语法。
- Java: 交集 [a-z&&[^aeiou]];差集写成与取反字符类的交集。
- .NET: 差集 [a-z-[aeiou]];不支持交集。
锚点与边界
锚点匹配的是位置而不是字符,因此不会消耗文本。
^ $字符串开头 / 结尾(加 m 时为行)不加 m 标志时,^ 和 $ 表示整个输入的开头和结尾;加上后表示每一行的开头和结尾。
/^\w+/gm
目标文本 “first line↵second line”
匹配 “first” “second”- PCRE / PHP: $ 也能匹配末尾 \n 之前的位置。
- Python re: $ 也能匹配末尾 \n 之前的位置。
- Java: $ 也能匹配末尾行终止符之前的位置。
- .NET: $ 也能匹配末尾 \n 之前的位置。
\b单词边界单词字符与非单词字符之间(或输入的边缘)。用于匹配完整单词。
/\bcat\b/g
目标文本 “cat concat cats cat.”
匹配 “cat” “cat”- JavaScript: 仅识别 ASCII 单词字符,即使加了 u 标志也一样。
- Go RE2: 仅识别 ASCII 单词字符。
\B非单词边界位于单词内部,例如只在 "cat" 是更长单词的一部分时匹配。
/\Bcat/g
目标文本 “concat cat bobcat”
匹配 “cat” “cat”\A \z \Z绝对开头 / 结尾无论是否为多行模式,都表示输入的开头和结尾。\Z 还允许末尾有一个换行符(Python 除外,在 Python 中它等同于 \z)。
\A\d+\z- JavaScript: 不加 m 标志使用 ^ 和 $。
- Python re: \A 和 \z(3.14+);\Z 表示绝对结尾,相当于其他引擎的 \z。
- Go RE2: \A 和 \z;没有 \Z。
\G上一次匹配的结尾上一次匹配结束的位置;用于匹配连续的片段。
\G\d- JavaScript: 没有 \G;y(sticky)标志可实现同样的“必须从这里开始”效果。
量词:贪婪、懒惰、占有
量词重复它前面的元素。贪婪模式(默认)先尽可能多地匹配再回退;懒惰模式(加 ?)尽可能少地匹配;占有模式(加 +)从不回退。
*零次或多次重复 0 次到无限次。
/ba*/g
目标文本 “b ba baaa”
匹配 “b” “ba” “baaa”+一次或多次重复 1 次到无限次。
/lo+l/g
目标文本 “lol loool ll”
匹配 “lol” “loool”?可选零次或一次。
/colou?r/g
目标文本 “color colour colouur”
匹配 “color” “colour”{n}正好 n 次正好重复 n 次。
/\d{3}/g
目标文本 “12 345 6789”
匹配 “345” “678”{n,}n 次或更多至少重复 n 次。
/\d{2,}/g
目标文本 “1 22 333”
匹配 “22” “333”{n,m}n 到 m 次重复 n 到 m 次,尽可能多。
/\d{2,3}/g
目标文本 “1 22 4444”
匹配 “22” “444”- Go RE2: 超过 1000 的次数会被拒绝。
{,m}最多 m 次重复 0 到 m 次。只有部分引擎支持;其他引擎会当作字面文本 "{,m}" 或报错。{0,m} 则在所有引擎中都有效。
\d{,3}- JavaScript: 不加 u 时是字面文本,加 u 时是语法错误;请写 {0,3}。
- PCRE / PHP: 仅 PCRE2 10.43+。
- Go RE2: 请写 {0,3}。
- Java: 请写 {0,3}。
- .NET: 被当作字面文本;请写 {0,3}。
.* .+贪婪(默认)先取尽可能长的匹配,再逐个退还字符,直到剩余部分能够匹配。这里它把两个标签都吞了进去。
/<.+>/g
目标文本 “<b>bold</b>”
匹配 “<b>bold</b>”*? +? ?? {n,m}?懒惰(非贪婪)取尽可能短的匹配。表达式“匹配过多”时,这通常就是解决办法。
/<.+?>/g
目标文本 “<b>bold</b>”
匹配 “<b>” “</b>”- Go RE2: 也可以用 U 标志,它会互换贪婪和懒惰模式。
*+ ++ ?+占有不回溯的贪婪模式:一旦匹配,字符永远不会退还。失败得更快,也能防止灾难性回溯。
"[^"]*+"- JavaScript: 不支持占有量词和原子组;可用 (?=(…))\1 模拟。
- Python re: Python 3.11+。
- Go RE2: 不需要:RE2 从不回溯。
- .NET: 使用原子组 (?>…)。
分组与反向引用
圆括号把元素组合起来,供量词和多选使用,并且(除非标记为非捕获)保存匹配到的内容。
( … )捕获组分组并捕获;按左括号出现的顺序从 1 开始编号。
/(\d{3})-(\d{4})/g
目标文本 “Call 555-0199 or 555-0123”
匹配 “555-0199” “555-0123”(?: … )非捕获组只分组不保存,组号保持稳定,匹配开销也略小。
/(?:ab)+/g
目标文本 “ababab ab a”
匹配 “ababab” “ab”(?<name> … )命名分组以名称捕获,之后可按名称读取(JavaScript 中为 match.groups.name)。
/(?<year>\d{4})-(?<month>\d{2})/g
目标文本 “Released 2026-10”
匹配 “2026-10”- PCRE / PHP: 也支持 (?'name'…) 和 (?P<name>…)。
- Python re: 只支持 (?P<name>…)。
- Go RE2: (?P<name>…);从 Go 1.22 起也接受 (?<name>…)。
- .NET: 也支持 (?'name'…)。
\1按编号反向引用匹配与之前某个分组捕获内容相同的文本。
/(\w)\1/g
目标文本 “bookkeeper”
匹配 “oo” “kk” “ee”- Go RE2: RE2 没有反向引用(否则会破坏其线性时间保证)。
\k<name>按名称反向引用与 \1 相同,但使用名称。示例匹配成对引号中的文本。
/(?<q>['"]).*?\k<q>/g
目标文本 “say "hi" or 'yo'”
匹配 “"hi"” “'yo'”- PCRE / PHP: 也支持 \k{name}、\g{name} 和 (?P=name)。
- Python re: 写作 (?P=name)。
a|b多选(或)匹配任意一边。备选项从左到右依次尝试,所以当一个是另一个的前缀时,把较长的放在前面。
/cat|dog/g
目标文本 “hotdog catalog”
匹配 “dog” “cat”(?> … )原子组分组一旦匹配成功,引擎就不会再回溯进去。
(?>a|ab)c- Python re: Python 3.11+。
- Go RE2: 不需要:RE2 从不回溯。
(?i) (?i: … )内联标志在表达式内部开启或关闭标志。(?i) 作用于表达式剩余部分;(?i:…) 只作用于该分组;(?-i:…) 关闭标志。
/(?i:hello) world/g
目标文本 “HELLO world HELLO WORLD”
匹配 “HELLO world”- JavaScript: 只支持限定范围的 (?i:…) / (?-i:…) 写法,适用于 i、m 和 s(ES2025)。开头的 (?i) 是语法错误。
- Python re: 全局 (?i) 必须位于表达式的最开头(从 3.11 起放在其他位置会报错);(?i:…) 可放在任意位置。
(?(1)yes|no)条件匹配如果第 1 组参与了匹配,则匹配 "yes",否则匹配 "no"。
(<)?\w+(?(1)>)(?R) (?1)递归 / 子程序调用重新进入整个表达式或某个分组,用于匹配嵌套结构,例如成对的括号。
\((?:[^()]|(?R))*\)- Python re: 第三方 regex 模块支持。
- .NET: 不支持递归;用平衡组 (?<open-close>…) 处理嵌套。
(?# … )内联注释引擎会忽略它。较长的注释请使用 x(扩展)标志。
\d{3}(?#area code)前瞻与后顾
环视检查当前位置旁边的内容,但不把它包含在匹配结果中。它们和锚点一样是零宽度的。
(?= … )正向前瞻后面紧跟着 …(不包含在匹配结果中)。
/\d+(?=px)/g
目标文本 “10px 20em 30px”
匹配 “10” “30”- Go RE2: RE2 不支持任何形式的环视。
(?! … )负向前瞻后面不是 …。其中的 \d 可防止引擎为了让检查通过而退还数字。
/\d+(?!px|\d)/g
目标文本 “10px 20em”
匹配 “20”(?<= … )正向后顾前面是 …(不包含在匹配结果中)。
/(?<=\$)\d+(?:\.\d\d)?/g
目标文本 “Cost: $42.50 or 42”
匹配 “42.50”- JavaScript: 任意长度(ES2018)。
- PCRE / PHP: 每个备选项的长度都必须有上限;从 PCRE2 10.43 起支持可变长度(默认最多 255)。
- Python re: 仅支持固定宽度:(?<=ab|cd) 可以,(?<=a+) 会报错。
- Java: 仅支持有上限的长度:内部不能有 * 或 +。
- .NET: 任意长度。
(?<! … )负向后顾前面不是 …。
/(?<!\$)\b\d+\b/g
目标文本 “$30 and 45”
匹配 “45”- PCRE / PHP: 长度规则与正向后顾相同。
- Python re: 仅支持固定宽度。
- Java: 仅支持有上限的长度。
\K重置匹配起点把目前为止匹配到的内容从结果中丢弃;相当于没有长度限制的后顾。
price: \K\d+- JavaScript: 使用 (?<=…) 或捕获组。
标志(修饰符)
JavaScript 把标志写在结尾斜杠之后(/x/gi)。其他语言则传入常量(re.I、Pattern.CASE_INSENSITIVE、RegexOptions.IgnoreCase)或使用内联 (?i)。
g全局(所有匹配)查找所有匹配,而不是找到第一个就停止。matchAll 和 replaceAll 必须使用它。
/o/g
目标文本 “foo boo”
匹配 “o” “o” “o” “o”- PCRE / PHP: 没有该标志:使用 preg_match_all() / preg_replace()。
- Python re: 没有该标志:使用 re.findall()、re.finditer()、re.sub()。
- Go RE2: 没有该标志:使用 FindAll… 系列方法。
- Java: 没有该标志:用 matcher.find() 循环。
- .NET: 没有该标志:使用 Regex.Matches()。
i忽略大小写不区分大小写匹配。
/hello/gi
目标文本 “Hello HELLO hello”
匹配 “Hello” “HELLO” “hello”- Python re: re.I / re.IGNORECASE 或 (?i)。
- Java: CASE_INSENSITIVE(除非加 UNICODE_CASE,否则仅限 ASCII)或 (?i)。
- .NET: RegexOptions.IgnoreCase 或 (?i)。
m多行^ 和 $ 匹配每行的开头和结尾,而不只是输入的两端。
/^-\s.+$/gm
目标文本 “- one↵- two↵three”
匹配 “- one” “- two”- Python re: re.M / re.MULTILINE。
- .NET: RegexOptions.Multiline。
s点号匹配换行让 . 也匹配换行符。不加该标志时,可移植的“任意字符”写法是 [\s\S]。
/<p>.*?</p>/gs
目标文本 “<p>a↵b</p>”
匹配 “<p>a↵b</p>”- Python re: re.S / re.DOTALL。
- Java: Pattern.DOTALL。
- .NET: 名为 RegexOptions.Singleline。
x扩展(自由空白)忽略表达式中的空白,# 开始注释,长表达式可以分多行排版。
(?x) \d{3} - \d{4} # local number- Python re: re.X / re.VERBOSE。
- Java: Pattern.COMMENTS。
- .NET: RegexOptions.IgnorePatternWhitespace。
uUnicode按码位处理输入(因此 . 能匹配一个完整的 emoji),启用 \p{…} 和 \u{…},并让无效转义报错。
/^.$/gu
目标文本 “😀”
匹配 “😀”- PCRE / PHP: PHP 的 u 修饰符(UTF-8 模式);加 (*UCP) 让 \w 和 \d 支持 Unicode。
- Python re: 无需标志:str 模式本身就是 Unicode;用 re.ASCII 可关闭。
- Go RE2: 没有该标志:Go 始终按 UTF-8 码位处理。
- Java: UNICODE_CASE 和 UNICODE_CHARACTER_CLASS(U)。
- .NET: 没有该标志:始终按 UTF-16 码元处理(一个 emoji 占两个)。
vUnicode 集合ES2024 对 u 的升级:字符类集合运算(--、&&)、嵌套字符类以及 \p{RGI_Emoji} 等字符串属性。不能与 u 同时使用。
/[\p{L}&&\p{ASCII}]+/gv
目标文本 “Ünïcode text”
匹配 “n” “code” “text”y粘连(sticky)每次匹配都必须从上一次结束的位置(lastIndex)开始。适合编写词法分析器。
/\d/gy
目标文本 “12a3”
匹配 “1” “2”- PCRE / PHP: 使用 \G。
- Python re: 使用 pattern.match(text, pos)。
- Java: 使用 \G 或 matcher.lookingAt()。
- .NET: 使用 \G。
d匹配索引添加 match.indices,包含每个捕获组的起止位置(ES2022)。
/(?<y>\d{4})/d- PCRE / PHP: 始终可获取偏移量(PREG_OFFSET_CAPTURE)。
- Python re: 始终可用:m.span(n)。
- Go RE2: 始终可用:FindStringSubmatchIndex。
- Java: 始终可用:matcher.start(n) / end(n)。
- .NET: 始终可用:Group.Index / Length。
Unicode 属性 \p{…}
属性转义按 Unicode 类别或文字系统匹配字符,这是跨语言匹配“任意字母”唯一可靠的方法。在 JavaScript 中需要 u 或 v 标志。
\p{L}任意字母所有文字系统中的字母:é、ß、東、д。
/\p{L}+/gu
目标文本 “naïve café 東京 123”
匹配 “naïve” “café” “東京”- PCRE / PHP: PHP 处理 UTF-8 输入时需要 u 修饰符。
- Python re: 使用第三方 regex 模块,或用 [^\W\d_] 表示“字母”。
\p{Lu} \p{Ll}大写 / 小写字母通用类别:Lu 大写字母、Ll 小写字母、N 数字、P 标点、S 符号、Z 分隔符。
/\p{Lu}/gu
目标文本 “Élan Vital”
匹配 “É” “V”\P{…}不具有该属性大写 P 表示取反:\P{L} 表示任何非字母字符。
/\P{L}+/gu
目标文本 “abc-123”
匹配 “-123”\pL单字母简写单字母类别可省略花括号。
\pL+- JavaScript: 必须加花括号:\p{L}。
- .NET: 必须加花括号:\p{L}。
\p{Script=Greek}文字系统某一种文字系统的字符。sc= 是简写;Script_Extensions(scx=)还包括多个文字系统共用的字符。
/\p{Script=Greek}+/gu
目标文本 “alpha α, beta β”
匹配 “α” “β”- PCRE / PHP: \p{Greek}、\p{sc:Greek} 或 \p{scx:Greek}。
- Go RE2: \p{Greek}。
- Java: 写作 \p{script=Greek}、\p{sc=Greek} 或 \p{IsGreek}。
- .NET: 只支持 \p{IsGreek} 这类命名区块(是码位范围,而非文字系统)。
\p{sc=Han}汉字(中文 / 日文)汉字表意文字。要匹配日文假名,再加上 \p{sc=Hiragana} 和 \p{sc=Katakana}。
/\p{sc=Han}+/gu
目标文本 “Tokyo 東京 2026 中文”
匹配 “東京” “中文”- PCRE / PHP: \p{Han}。
- Python re: 使用 [\u4e00-\u9fff] 这样的范围(只覆盖基本区块)。
- Go RE2: \p{Han}。
- Java: 也可用 \p{IsHan}。
- .NET: 只支持区块,例如 \p{IsCJKUnifiedIdeographs}。
\p{RGI_Emoji}Emoji(完整序列)加 v 标志时,可匹配完整的 emoji,包括肤色和家庭组合序列。加 u 时,\p{Extended_Pictographic} 只匹配单个图形字符。
/\p{RGI_Emoji}/gv
目标文本 “Go 👍🏽 team 👨👩👧!”
匹配 “👍🏽” “👨👩👧”- PCRE / PHP: 较新的 PCRE2(10.40+)可通过布尔属性匹配单个码位;没有序列属性。
- Java: \p{IsEmoji} 匹配单个码位(Java 21+)。
\X字素簇用户感知上的一个字符,例如 e 加组合重音符,或一个国旗 emoji。
\X- JavaScript: 用 Intl.Segmenter 按字素拆分。
- Python re: regex 模块支持。
替换语法
替换字符串中该怎么写。这是各语言差异最大的地方,所以你所用语言那一栏比 JavaScript 示例更重要。
$&整个匹配插入匹配到的全部文本。
/\d+/g
目标文本 “3 apples, 12 pears”
替换为 “[$&]” → “[3] apples, [12] pears”- PCRE / PHP: preg_replace 中用 $0 或 \0。
- Python re: \g<0>。
- Go RE2: ${0} 或 $0(Expand / ReplaceAllString)。
- Java: $0.
- .NET: 也可用 $0。
$1编号分组插入第 1 组捕获的内容。交换两个单词:
/(\w+)\s(\w+)/g
目标文本 “hello world”
替换为 “$2 $1” → “world hello”- PCRE / PHP: 也可用 \1 和 ${1}。
- Python re: \1 或 \g<1>(使用原始字符串 r"\1")。
- Go RE2: 后面紧跟字母或数字时用 ${1}x,否则 Go 会把 $1x 当作名为 "1x" 的分组。
$<name>命名分组插入命名分组的内容。把 ISO 日期改写成 日/月/年:
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/g
目标文本 “2026-10-18”
替换为 “$<d>/$<m>/$<y>” → “18/10/2026”- PCRE / PHP: preg_replace 不支持命名引用;请使用组号或 preg_replace_callback()。
- Python re: \g<name>。
- Go RE2: ${name}(或 $name)。
- Java: ${name}。
- .NET: ${name}。
$$字面美元符号在替换字符串中转义 $。
/(\d+)/g
目标文本 “Price: 20”
替换为 “$$$1” → “Price: $20”- PCRE / PHP: 后面不是数字或 { 的 $ 本来就是字面字符;在它之后引用分组请写 ${1}。
- Python re: $ 没有特殊含义;反斜杠要转义为 \\。
- Java: \$(Matcher.quoteReplacement() 可转义整个字符串)。
$` $'匹配之前 / 之后的文本插入输入中位于匹配之前或之后的内容。很少用到,但偶尔很方便。
/=/
目标文本 “key=value”
替换为 “ is set ($') and was ($`) ” → “key is set (value) and was (key) value”常用表达式(附真实局限)
大家搜索最多的表达式,写得易读,并且不会出现灾难性回溯。每条都说明了它做不到什么。
Email (practical)查找类似邮箱的字符串本地部分、@,以及至少含一个点的域名。
/[\w.+-]+@[\w-]+(?:\.[\w-]+)+/g
目标文本 “Write to ana.lee+news@example.co.uk or bob@test.dev.”
匹配 “ana.lee+news@example.co.uk” “bob@test.dev”注意: 会拒绝合法但少见的地址(带引号的本地部分、非 ASCII 域名),也会接受一些无效地址(a..b@x.y)。任何正则都无法判断邮箱是否真实存在:请发送确认邮件。
URL查找文本中的 http(s) 链接遇到空白、引号和尖括号时停止,并去掉末尾的句号、逗号等标点。
/https?://[^\s<>"]*[^\s<>".,;:!?)]/g
目标文本 “See https://example.com/a?b=1, or (http://test.dev/x).”
匹配 “https://example.com/a?b=1” “http://test.dev/x”注意: 适合把文本中的网址转成链接,不适合做校验。要检查 URL,请使用所用语言的 URL 解析器(JavaScript 中为 new URL()),再检查协议和主机。
IPv4 address四段 0–255 的数字每段限定在 0–255,且不带前导零。
/\b(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}\b/g
目标文本 “10.0.0.1 256.1.1.1 192.168.1.254”
匹配 “10.0.0.1” “192.168.1.254”注意: 不支持 IPv6、CIDR 后缀或端口。校验时请使用 IP 解析器(Python ipaddress、Go net/netip、Node net.isIP)。
Date YYYY-MM-DDISO 8601 日期月份 01–12,日期 01–31。
/\b\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\b/g
目标文本 “2026-10-18, 2026-13-01, 2026-02-31”
匹配 “2026-10-18” “2026-02-31”注意: 只检查格式:2026-02-31 也能通过。要排除不存在的日期,请用日期库解析。
Date MM/DD/YYYY美式日期一位或两位的月和日,四位的年。
/\b(?:0?[1-9]|1[0-2])/(?:0?[1-9]|[12]\d|3[01])/\d{4}\b/g
目标文本 “Due 10/18/2026 or 1/5/2027, not 13/01/2026”
匹配 “10/18/2026” “1/5/2027”注意: 01/02/2026 在美国是 1 月 2 日,在其他大多数地方是 2 月 1 日;正则无法知道本意是哪个。
Phone (North America)(416) 555-0199 及其变体十位数字,可带括号、空格、点或短横线。
/\(?\b\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
目标文本 “(416) 555-0199, 416.555.0199, 4165550199”
匹配 “(416) 555-0199” “416.555.0199” “4165550199”注意: 仅适用于北美号码。国际号码请使用 libphonenumber 等库;并以 E.164 格式存储号码(见下一行)。
Phone (E.164)国际格式 +CC…加号、不以 0 开头的国家代码,总共最多 15 位数字。
/^\+[1-9]\d{1,14}$/gm
目标文本 “+14165550199↵+447911123456↵0044791112”
匹配 “+14165550199” “+447911123456”注意: 只检查 E.164 格式,不检查号码是否已分配,也不检查长度是否符合所在国家的规定。
Hex colour#rgb、#rgba、#rrggbb、#rrggbbaaCSS 接受的四种长度。
/#(?:[\da-fA-F]{8}|[\da-fA-F]{6}|[\da-fA-F]{3,4})\b/g
目标文本 “#fff #244b3f #12345 #ff000080 #1234567”
匹配 “#fff” “#244b3f” “#ff000080”注意: 也会匹配较长文本中的内容,例如带 #片段 的 URL;要校验单个值,请用 ^…$ 锚定。
URL sluglowercase-words-with-hyphens小写字母和数字,用单个连字符分隔。
/^[a-z0-9]+(?:-[a-z0-9]+)*$/gm
目标文本 “my-post-2026↵My Post↵-bad-↵good”
匹配 “my-post-2026” “good”注意: 仅限 ASCII。要根据标题生成 slug,请使用 URL slug 生成器,而不是正则。
Trim whitespace首尾空格替换为空字符串。不加 m 标志时,^ 和 $ 表示整个文本的两端。
/^\s+|\s+$/g
目标文本 “ padded text ”
替换为 “” → “padded text”注意: 所有现代语言都有内置的 trim(),更快也更清晰;只在无法调用代码的地方(编辑器、配置文件)使用正则。
Collapse spaces连续空格合并为一个把两个或更多空格或制表符替换为一个空格。
/[ \t]{2,}/g
目标文本 “too many ⇥ spaces”
替换为 “ ” → “too many spaces”Duplicate wordsthe the、is is紧跟着自身的单词。加 i 后,"The the" 也能被找出来。
/\b(\w+)\s+\1\b/gi
目标文本 “This is is a test test of The the editor”
匹配 “is is” “test test” “The the”注意: 需要反向引用,所以在 Go 中不可用。"had had" 和 "that that" 有时是正确的英语。
Password rules小写、大写、数字,12 位以上每个前瞻从开头检查一条规则;.{12,} 设定长度。
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$/gm
目标文本 “short1A↵alllowercase123↵GoodPassword42”
匹配 “GoodPassword42”注意: NIST SP 800-63B 不建议设置字符组合规则:应要求足够长度,并对照已泄露密码列表进行检查。
UUID8-4-4-4-12 位十六进制版本 1–8,带 RFC 9562 变体位。
/\b[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\b/gi
目标文本 “id 3f2b8c1e-9d4a-4b7e-8f6a-1c2d3e4f5a6b and 00000000-0000-0000-0000-000000000000”
匹配 “3f2b8c1e-9d4a-4b7e-8f6a-1c2d3e4f5a6b”注意: 会拒绝 nil UUID(全为 0)和 max UUID(全为 f),而它们是合法的特殊值。
这是一份静态参考:搜索和筛选都在浏览器中进行,“试用”链接会打开我们的浏览器端正则表达式测试工具。 浏览全部免费工具.
发现问题,或者觉得哪里可以更好?每条消息我们都会阅读,并尽快修复。
这份正则表达式速查表列出了你可能用到的每一个正则语法元素,从 \d 和 \b 到后行断言、占有量词和 \p{Script=Greek},每个都有简短的说明和一个准确展示其匹配内容的示例。每个示例都有“在正则表达式测试工具中试用”链接,会打开我们的正则表达式测试工具,并预先填好模式、标志和示例文本,你可以修改它并观察匹配结果的变化。
正则表达式看起来到处都一样,其实并不一样。后行断言在 JavaScript 和 .NET 中不限长度,在 Python 中必须定宽,在 Java 和 PCRE 中有长度上限,在 Go 中则根本没有。Python 的命名分组写作 (?P<name>…),PHP 不能在替换中使用名称,而且只有部分引擎认识 \A、\K 或 (?R)。方言选择器会显示每个语法元素在 JavaScript、PCRE/PHP、Python、Go、Java 和 .NET 中的支持情况,并在有替代语法时一并给出。示例本身在 JavaScript 中运行;对于其他语言,请阅读说明,并在上线前用该语言测试。
使用方法
- 搜索某个语法元素(\b、lookahead)或某项任务(email、trim、duplicate words),或通过顶部的标签跳转到相应章节。
- 在方言栏中选择你的语言。它不支持的语法元素会被淡化显示,每个条目下的说明会给出你的语言所用的替代语法。
- 点击“在正则表达式测试工具中试用”实时运行示例,然后在那里编辑模式或文本。
- 使用条目旁边的 # 直接链接到该条目,或使用“打印 / 保存为 PDF”获取紧凑的双栏版本。
常见问题
贪婪量词和懒惰量词有什么区别?
贪婪量词(*、+、{n,m})会尽可能多地匹配字符,如果模式的其余部分匹配失败,再退还一些;懒惰量词(*?、+?、{n,m}?)则尽可能少地匹配。对于 <b>bold</b>,<.+> 会匹配整个字符串,而 <.+?> 会分别匹配 <b> 和 </b>。占有量词(*+、++)是贪婪的,且从不退还字符;JavaScript、Go 和 .NET 没有占有量词。
哪些语言支持后行断言?
JavaScript(自 ES2018 起)和 .NET 允许任意长度的后行断言。Java 要求有长度上限,因此其中不能用 * 或 +。Python 的 re 模块只接受定宽的后行断言。PCRE2 在 10.43 之前要求每个分支长度固定,10.43 加入了有上限(默认 255 个字符)的变长后行断言。Go 的 RE2 引擎完全不支持先行和后行断言。
如何匹配任意字母,包括带重音的字母和非拉丁字母?
使用 Unicode 属性 \p{L}。在 JavaScript 中需要 u 或 v 标志(/\p{L}+/u);PCRE、Go、Java 和 .NET 直接支持。[a-zA-Z] 会漏掉 é、ß 以及所有非拉丁文字,而 \w 在 JavaScript 和 Go 中只匹配 ASCII。Python 内置的 re 没有 \p{…};请使用第三方 regex 模块,或使用 [^\W\d_],它在 Python 3 中匹配 Unicode 字母。
如何在替换中使用捕获分组?
这取决于语言:JavaScript、Java、.NET、Go 和 PHP 用 $1;Python 用 \1 或 \g<1>。命名分组在 JavaScript 中为 $<name>,在 Java、.NET 和 Go 中为 ${name},在 Python 中为 \g<name>;PHP 的 preg_replace 没有命名形式,只能用编号。整个匹配在 JavaScript 和 .NET 中为 $&,在 Java 和 PHP 中为 $0,在 Python 中为 \g<0>。
为什么我的正则在 JavaScript 中能用,在 Python 中却不行(或者反过来)?
常见原因有:命名分组(JavaScript 中为 (?<name>),Python 中为 (?P<name>));\p{…} 属性(JavaScript 支持,Python re 不支持);后行断言长度(JavaScript 任意,Python 固定);内联标志(开头的 (?i) 在 Python 中可用,在 JavaScript 中却是错误,JavaScript 只有限定作用范围的 (?i:…));以及 \d 或 \w 在 Python 中匹配 Unicode 数字和字母,在 JavaScript 中只匹配 ASCII。还要注意 Python 字符串转义:模式要写成原始字符串,r"\d+"。
用正则表达式验证邮箱地址安全吗?
只适合做格式检查。像 [\w.+-]+@[\w-]+(?:\.[\w-]+)+ 这样实用的模式能发现拼写错误,但会拒绝一些合法地址(带引号的本地部分、国际化域名),也会接受一些不合法的地址。没有任何模式能告诉你邮箱是否真实存在,所以宽松地检查格式,然后发送一封确认邮件。
编写可在多种语言中使用的模式
如果一个模式必须在多个引擎中运行(共享的验证规则、由不同语言的服务读取的配置文件),就只使用公共子集。以下内容在本页的全部六种引擎中行为一致:
• 字面字符、\. 和 \$ 之类的转义,以及字符类 [abc]、[^abc] 和 [a-z]。
• \d、\s 和 \w,前提是输入为 ASCII(Python 和 .NET 也会匹配 Unicode 数字和字母)。
• ^ 和 $、\b、选择分支、捕获分组和非捕获分组。
• 贪婪和懒惰量词:*、+、?、{n}、{n,m} 及其带 ? 的形式。
避免使用环视(Go 不支持)、反向引用(Go 不支持)、占有量词和原子分组(JavaScript、Go 和 .NET 缺少其中之一或两者)、命名分组(Python 语法不同)以及 \p{…}(Python 的 re 不支持)。如果需要用到其中某项,就为每种语言各保留一份模式,并分别测试。
避免灾难性回溯
回溯型引擎(JavaScript、PCRE、Python、Java、.NET)在某些模式上可能耗费指数级的时间——当一个带量词的分组能以多种方式匹配同一段文本时,例如 (a+)+$ 或 (\w|\d)*x。面对一个几乎能匹配的长输入,引擎会在失败前尝试每一种拆分方式,Web 服务器可能因此卡死在一个请求上。这就是正则表达式拒绝服务(ReDoS)问题。
修复方法很机械:避免对相同字符嵌套量词;让各选择分支互斥;在知道分隔符时,用 [^"]* 这样的否定字符类代替 .*?;在引擎支持时使用占有量词或原子分组;匹配前限制输入长度。.NET 还提供 RegexOptions.NonBacktracking 和匹配超时,PCRE 可以设置匹配上限,而 Go 的 RE2 引擎通过不支持需要回溯的功能来保证线性时间。
在字符串中转义正则表达式
实际代码中的大多数正则 bug 其实是字符串转义 bug,而不是正则本身的 bug。反斜杠对语言的字符串字面量和正则引擎都有特殊含义,所以写成普通字符串的模式需要双反斜杠。
• JavaScript:字面量 /\d+/ 需要一个反斜杠;new RegExp("\\d+") 需要两个。String.raw`\d+` 可以避免加倍。
• Python:始终使用原始字符串 r"\d+";否则 "\b" 是退格字符,而不是单词边界。
• Java 和 C#:普通字符串中写作 "\\d+"(Java 文本块同样会处理转义);C# 的逐字字符串 @"\d+" 会原样保留反斜杠。
• Go:配合 regexp.MustCompile 时,惯例是使用反引号原始字符串 `\d+`。
• PHP:模式包含分隔符 '/\d+/',单引号字符串会原样保留大多数反斜杠。
相关免费工具
- 正则表达式测试 — 用示例文本测试正则表达式,实时高亮匹配结果,显示捕获组并预览替换效果。免费,在浏览器中运行。
- Git 速查表 — 按你想做的事整理 Git 命令:撤销上一次提交、重命名分支、删除远程分支。优先给出新式 switch/restore 命令并附经典写法,危险操作有醒目标记。
- Markdown 速查表 — 每个 Markdown 元素都附源码和渲染预览,涵盖扩展语法(表格、任务列表、脚注、数学公式、Mermaid、提示框),另有 9 个平台的兼容性对照表和实时练习区。
- Cron 表达式生成器 — 用下拉菜单生成 cron 定时计划,或粘贴现有表达式,用通俗语言解读,并查看接下来 10 次运行时间(本地时区和 UTC)。免费,在浏览器中运行。
- 文本对比(Diff) — 比较文本、代码或 JSON 文件的两个版本,准确看出哪些行、词和字符发生了变化。