正则可视化

正则→railroad diagram/高亮

424 次访问

正则可视化 · Token 分解

复杂正则建议用 regex101.comregexper.com
字面量 元字符 / 字符类 分组 量词 锚点

示例(点击应用)

关于本工具

了解工具定位 · 使用场景 · 对比优势

使用场景

🐛

日志解析调试

运维人员面对 Nginx 错误日志中混杂的 IP、时间戳、URL 参数,手写正则经常漏掉边界情况。将正则输入本工具,立即生成铁路图,分支与循环结构一目了然,一眼看出 '\d+' 是否匹配了端口号、'?' 是否让分组变成可选,避免线上误判。

📝

表单输入校验

前端开发者在写手机号 / 邮箱 / 身份证正则时,经常因为 '^' 和 '$' 的位置、量词范围导致校验过松或过严。把写好的正则丢进工具,铁路图会直观显示匹配路径的起点与终点,配合高亮预览,能立即发现 '\d{11}' 是否允许了 12 位数字。

📚

正则表达式教学

培训讲师讲解 '捕获组' 和 '非捕获组' 的区别时,学生光看文本很难理解分组对回溯的影响。在工具中输入 '(\d{4})-(\d{2})',铁路图清晰展示两个捕获组的分叉路径,配合高亮演示匹配过程,比口头解释效率高 3 倍。

🔍

数据清洗规则验证

数据分析师从 CSV 中提取特定格式的日期(YYYY-MM-DD),但实际数据里混着 '2024/1/5' 和 '2024-01-5'。在工具中输入 '\d{4}-\d{2}-\d{2}',铁路图会显示量词 '\d{2}' 只匹配两位数字,从而暴露 '1/5' 无法被匹配,从而修正规则为更宽松的格式。

⚙️

爬虫规则调试

爬虫工程师写正则提取 HTML 中特定 class 的链接,经常因为 '.' 匹配了换行符或 '.*' 的贪婪性导致抓取范围扩大。将正则输入工具,铁路图可视化每个量词的匹配路径,配合高亮预览,能快速定位 '.*' 是否跨过了不该匹配的标签。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具Regex101传统方法(文本编辑器)
数据隐私纯浏览器处理,正则与文本不上传服务器部分功能需上传至服务器分析本地文件操作,无网络传输
可视化输出生成铁路图与高亮,直观展示匹配路径提供正则分解与匹配高亮,无铁路图仅文本高亮或手动标记
处理速度即时反馈,输入即渲染复杂正则解析需 1-3 秒依赖编辑器性能,大文件可能卡顿
调试辅助通过图形化结构发现逻辑错误提供正则步骤调试与错误提示无结构化调试,依赖人工排查
学习门槛图形化降低理解难度,适合初学者需正则基础,侧重进阶调试无辅助,需完全掌握正则语法
文件大小限制受浏览器内存限制(通常 <50MB)免费版限制输入长度,高级版无限制仅受本地硬件限制
离线可用性完全离线可用(单 HTML 文件)需联网使用完全离线

使用指南

上手步骤 · 输入输出 · 避坑提示

输入输出示例7 个典型场景,覆盖常规、边界与易错

输入输出说明
^[a-z]+$一条水平轨道,起始锚点(^),然后一个或多个小写字母的循环节点([a-z]+),最后结束锚点($)典型场景:匹配纯小写字母字符串
\d{3}-\d{4}三个数字的节点(\d{3}),连字符节点,四个数字的节点(\d{4})常见用法:匹配电话号码或邮编片段
a|b一个分支节点,两条平行路径:左侧路径为 'a' 字符节点,右侧路径为 'b' 字符节点边界 case:最简单的分支结构,展示或逻辑
(?i)hello一个内联修饰符节点((?i)),后接 'hello' 字符序列节点边界 case:展示内联模式修饰符在图中如何表示
\b\w+\b单词边界锚点(\b),一个或多个单词字符的循环节点(\w+),单词边界锚点(\b)典型场景:匹配完整单词
a{3,5}一个 'a' 字符节点,带有一个范围量词标记(3 到 5 次)易错 case:新手常混淆 {3,5} 与 {3,} 的图示区别
.一个通配符节点(匹配除换行符外的任意字符)边界 case:最简单的单字符通配符,展示点号特殊含义

常见错误对照8 个常踩的坑 · 错误 → 修复

1. 量词边界不匹配导致无限循环

错误
a*
修复
a{0,5} 或 a+

a* 匹配零个或多个 a,在可视化图中会显示为无限循环箭头(ε 到自身),实际匹配时若目标字符串不含 a 仍匹配空串,容易误导对匹配行为的理解。

2. 转义字符写错层

错误
\d{3}-\d{4}
修复
\d{3}-\d{4}

在 JavaScript 字符串中写正则时需双重转义(\\d),但工具输入框直接接收正则字面量,只需写 \d。多一层反斜杠会被视为字面量反斜杠+字母d。

3. 忘记锚点导致部分匹配

错误
^[A-Z]{2}\d{6}$
修复
^[A-Z]{2}\d{6}$

可视化图会清晰显示 ^ 和 $ 锚点。若缺少锚点,正则匹配字符串中任意位置的子串,而非整个字符串,导致看似不符合格式的输入也被高亮。

4. 字符类中连字符位置错误

错误
[a-z-A-Z]
修复
[a-zA-Z] 或 [A-Za-z]

连字符在字符类中间时被解释为范围(a-z 到 A 无意义),可视化图会显示为三个独立字符 a、-、z、A、Z 而非预期范围。正确做法是把连字符放首位或末尾。

5. 量词修饰分组而非单个字符

错误
ab+
修复
(ab)+

ab+ 匹配 a 后跟一个或多个 b,可视化图显示为 a 后接 b+ 循环。若意图匹配整个 ab 重复,必须用分组 (ab)+,图中会显示为分组循环。

6. 反向引用编号混淆

错误
(\d{3})-(\d{4})\1
修复
(\d{3})-(\d{4})\2

\1 引用第一个捕获组,\2 引用第二个。可视化图会标注捕获组编号。若写错编号,实际匹配时引用的是错误分组内容,导致匹配失败。

7. 忽略贪婪/懒惰量词差异

错误
.*
修复
.*?

.* 贪婪匹配尽可能多字符,可视化图中显示为一条长箭头直接到末尾;.*? 懒惰匹配最少字符,图中显示为逐字符尝试。在 HTML 解析等场景中差异巨大。

8. 非捕获组写成捕获组

错误
(?:\d{4})
修复
(?:\d{4})

非捕获组 (?:...) 在可视化图中显示为灰色虚线框,捕获组 (...) 显示为实线框并编号。若不需要反向引用,用非捕获组可减少性能开销和编号混乱。

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

R = (S → N) ∪ (E → N) ∪ (Q → N)

变量说明

  • R — 最终生成的铁路图节点集合
  • S — 正则表达式中的序列(连接)结构
  • E — 正则表达式中的分支(选择)结构
  • Q — 正则表达式中的量词(重复)结构

示例

正则表达式 `a(b|c)*` 的铁路图生成:S 对应 `a` 与 `(b|c)*` 的串联,E 对应 `b|c` 分支,Q 对应 `*` 量词。最终图包含:起始→a→分支(b 或 c)→循环返回分支→结束。

适用范围

适用于将标准 PCRE/ECMAScript 正则表达式转换为铁路图。不支持反向引用、零宽断言等高级特性,仅覆盖序列、分支、量词三种基本结构。

原理图

输入正则/^[a-z]+$/解析语法树AST 构建(浏览器内)生成铁路图Railroad Diagram+ 高亮渲染SVG输入测试文本abc123匹配引擎(浏览器内)高亮匹配结果abc
用户输入 本地处理(浏览器内) 输出结果 渲染

开发者集成

3 种主流语言 · 复制即用

import re
from graphviz import Digraph

# 将正则表达式转换为铁路图(简化版:仅展示分支和序列)
def regex_to_railroad(pattern):
    dot = Digraph(comment=pattern)
    dot.attr(rankdir='LR')
    dot.node('start', 'Start', shape='circle')
    dot.node('end', 'End', shape='doublecircle')
    
    # 解析简单分支: a|b
    if '|' in pattern:
        parts = pattern.split('|')
        dot.node('branch', '|', shape='diamond')
        dot.edge('start', 'branch')
        for i, part in enumerate(parts):
            dot.node(f'part{i}', part, shape='box')
            dot.edge('branch', f'part{i}')
            dot.edge(f'part{i}', 'end')
    else:
        dot.edge('start', 'end', label=pattern)
    
    return dot

# 示例:匹配数字或字母
dot = regex_to_railroad(r'\d+|[a-z]+')
dot.render('regex_railroad', format='png', cleanup=True)
print('铁路图已保存为 regex_railroad.png')
package main

import (
	"fmt"
	"regexp"
	"strings"
)

// 高亮匹配部分:用 ANSI 颜色标记
func highlightMatch(pattern, text string) string {
	re := regexp.MustCompile(pattern)
	return re.ReplaceAllStringFunc(text, func(match string) string {
		// 红色背景高亮
		return "\033[41m" + match + "\033[0m"
	})
}

func main() {
	pattern := `\d{3,4}`
	text := "联系号码: 010-1234 或 021-567"
	
	result := highlightMatch(pattern, text)
	fmt.Println("高亮结果:")
	fmt.Println(result)
	// 输出(终端可见颜色):联系号码: [红色]010[/红色]-1234 或 [红色]021[/红色]-567
	
	// 同时输出匹配位置
	re := regexp.MustCompile(pattern)
	matches := re.FindAllStringIndex(text, -1)
	for _, m := range matches {
		fmt.Printf("匹配位置 [%d:%d]: %s\n", m[0], m[1], text[m[0]:m[1]])
	}
}
// 正则可视化:生成匹配高亮 HTML
function highlightRegex(text, pattern, flags = 'g') {
  const re = new RegExp(pattern, flags);
  let result = '';
  let lastIndex = 0;
  let match;
  
  while ((match = re.exec(text)) !== null) {
    // 非匹配部分
    result += escapeHtml(text.slice(lastIndex, match.index));
    // 匹配部分用 <mark> 高亮
    result += '<mark>' + escapeHtml(match[0]) + '</mark>';
    lastIndex = re.lastIndex;
  }
  // 剩余部分
  result += escapeHtml(text.slice(lastIndex));
  return result;
}

function escapeHtml(str) {
  return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

// 示例
const text = 'Email: user@example.com, admin@test.org';
const pattern = '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}';
const html = highlightRegex(text, pattern);
document.body.innerHTML = html;
// 页面显示:Email: <mark>user@example.com</mark>, <mark>admin@test.org</mark>

常见问题

8 个高频疑问

正则可视化生成的图怎么用?能直接复制到文档里吗?
工具生成的 railroad diagram 是 SVG 格式,在结果区域右键点击图片,选择「复制图片」或「另存为」,可以粘贴到 Word、Markdown、Notion 等文档中。如果需要嵌入网页,右键复制 SVG 代码(或直接拷贝页面中 `<svg>` 标签的 HTML),粘贴到 HTML 文件中即可。注意:部分聊天软件(如微信)不支持直接粘贴 SVG,建议先保存为 .svg 文件再拖入。
我写了一个很复杂的正则,为什么图形显示不全或者乱成一团?
工具对超长正则(超过 200 个字符)或嵌套过深(如多个分组套分组)的表达式,渲染时可能会自动缩放或截断。建议先拆分成多个子正则分别可视化,确认每个子模式正确后再合并。另外,如果正则中包含 `(?R)` 递归匹配或 `(?(condition)yes|no)` 条件分支,部分引擎特有的语法可能无法正确解析,图形会显示为「未识别」节点。
这个工具支持 JavaScript 的零宽断言和命名分组吗?
支持。JavaScript 的 `(?=...)`(正向先行断言)、`(?!...)`(负向先行断言)、`(?<=...)`(正向后行断言)和 `(?<!...)`(负向后行断言)都能正确识别并显示为菱形分支节点。命名分组 `(?<name>...)` 和反向引用 `\k<name>` 也支持,图形中会标注分组名称。不过注意,JavaScript 不支持 `(?|...)` 分支重置和 `(?(DEFINE)...)` 定义块,这些语法会显示为错误节点。
为什么我输入一个简单的 `\d+` 但它把数字也高亮了?这不是可视化工具吗?
高亮功能是「实时匹配预览」——你在测试文本区域输入的文本中,匹配到的部分会被高亮显示。`\d+` 匹配一个或多个数字,所以文本中的数字会全部高亮。如果你只想看铁路图(railroad diagram)而不想看匹配高亮,可以清空测试文本区域,或者关闭页面上的「高亮匹配」开关(如果有的话)。铁路图本身只展示正则的结构逻辑,不涉及文本匹配。
这个工具和 regex101 有什么区别?哪个更好用?
核心区别:本工具侧重「正则结构的可视化理解」,regex101 侧重「调试和测试」。regex101 提供详细的匹配步骤、捕获组捕获内容、引擎性能分析,适合调试复杂正则;本工具直接生成铁路图,适合新手理解正则的「分支」「循环」「可选」等结构关系,也适合写文档时生成图形。建议:学习正则结构用本工具,调试匹配逻辑用 regex101,两者互补。
正则可视化能处理中文和 Unicode 字符吗?比如匹配汉字或全角符号。
可以。测试文本区域支持直接输入中文、日文、韩文等 Unicode 字符。正则中使用 `\uXXXX` 或 `\p{Script=Han}`(如果浏览器支持)都能正确匹配并高亮。铁路图对 `[\u4e00-\u9fa5]` 这类字符集也会正常显示为区间节点。注意:如果正则中包含 `\w`,它默认只匹配 `[a-zA-Z0-9_]`,不包含中文,需要改用 `[\u4e00-\u9fa5]` 或 `\p{L}`(Unicode 属性)。
我输入正则后页面卡住了,是不是死机了?
大概率不是死机,而是正则中包含了「灾难性回溯」的模式。例如 `(a+)+b` 这样的嵌套重复,在匹配失败时会导致浏览器引擎尝试指数级的分支路径,造成页面假死几秒甚至几十秒。解决办法:在正则末尾加一个「锚点」如 `$` 或 `\z` 来加速失败判断;或者简化嵌套重复结构。如果无法修改正则,可以刷新页面,但再次输入同样模式仍会卡住——建议先用 regex101 调试确认无性能问题,再粘贴到本工具生成图形。
生成的铁路图能导出成其他格式吗?比如 PNG 或 PDF?
目前工具直接导出的是 SVG 格式(矢量图)。如果需要 PNG 或 PDF,可以这样做:在浏览器中右键 SVG 图片 →「在新标签页中打开」→ 按 Ctrl+P(或 Cmd+P)打印 → 选择「另存为 PDF」即可得到 PDF 版本。或者使用在线 SVG 转 PNG 工具(如 svg2png.com)转换。注意:SVG 中的文字是真正的文本,转换后不会变成像素,清晰度比直接截图高。
选择 打开 +新窗口 esc关闭