Julia 正则表达式

Julia 正则表达式(Regex)完全指南(中文版)

“强大、原生、高性能” —— Julia 的正则表达式是文本处理的核武器


一、什么是正则表达式?

正则表达式(Regular Expression) 是一种用模式(pattern)匹配文本的工具。

Julia 中使用 Regex 类型,原生支持 PCRE(Perl 兼容正则表达式)引擎。

r"pattern"     # 创建正则表达式

二、创建正则表达式

# 基本语法
r"abc"          # 匹配 "abc"
r"\d+"          # 匹配一个或多个数字
r"^hello"       # 以 hello 开头
r"world$"       # 以 world 结尾
r"\s"           # 匹配空白字符

# 忽略大小写
r"julia"i       # i = ignore case

# 多行模式
r"^start"m      # m = multiline,每行开头

# 点匹配换行
r"."s           # s = dotall

# 组合标志
r"pattern"ims

三、核心元字符(Metacharacters)

元字符含义示例
.匹配任意字符(除换行)r"a.c" → “abc”, “axc”
^行首r"^abc" → 匹配行首
$行尾r"abc$"
*0次或多次r"a*" → “”, “a”, “aaa”
+1次或多次r"a+" → “a”, “aaa”
?0次或1次r"a?" → “”, “a”
{n}恰好 n 次r"a{3}" → “aaa”
{n,}至少 n 次r"a{2,}"
{n,m}n 到 m 次r"a{2,4}"
|r"cat|dog"
( )分组r"(ab)+" → “ab”, “abab”
[ ]字符集r"[a-z]"
[^ ]否定字符集r"[^0-9]"

四、字符类(Character Classes)

含义
\d数字 [0-9]
\D非数字
\w单词字符 [a-zA-Z0-9_]
\W非单词字符
\s空白字符(空格、制表、换行)
\S非空白
\b单词边界
\B非单词边界
r"\d{4}-\d{2}-\d{2}"    # 匹配日期 2025-10-26
r"\bcat\b"              # 匹配独立单词 "cat",不匹配 "category"

五、常用匹配函数

函数说明返回值
occursin(r, s)是否包含Bool
match(r, s)首次匹配RegexMatchnothing
eachmatch(r, s)所有匹配迭代器
matchall(r, s)所有匹配字符串Vector{String}
s = "Email: alice@example.com, bob@site.org"

# 1. 是否包含邮箱
occursin(r"\w+@\w+\.\w+", s)    # true

# 2. 首次匹配
m = match(r"\w+@\w+\.\w+", s)
m.match      # "alice@example.com"
m.offset    # 7(起始位置)
m.captures  # [](无分组)

# 3. 所有匹配
for m in eachmatch(r"\w+@\w+\.\w+", s)
    println(m.match)
end
# alice@example.com
# bob@site.org

六、分组与捕获(Capturing Groups)

r = r"(\w+)@(\w+)\.(\w+)"

m = match(r, "alice@example.com")
m[1]     # "alice"(第一个分组)
m[2]     # "example"
m[3]     # "com"
m.captures  # ["alice", "example", "com"]

命名分组(Named Capture)

r = r"(?<user>\w+)@(?<domain>\w+)\.(?<tld>\w+)"

m = match(r, "bob@site.org")
m[:user]    # "bob"
m["domain"] # "site"
m[:tld]     # "org"

七、替换(replace)

s = "Price: $100, Tax: $15"

# 简单替换
replace(s, r"\$\d+" => "XX")    # "Price: XX, Tax: XX"

# 使用捕获组
replace(s, r"\$(\d+)" => s -> "$(parse(Int, s[1]) * 2)")  
# "Price: 200, Tax: 30"

# 命名分组替换
replace(s, r"\$(?<amt>\d+)" => s -> "$(s[:amt] * 10)")  
# "Price: 1000, Tax: 150"

八、前向肯定查找(Lookahead)

语法含义
(?=...)正向前瞻
(?!...)负向前瞻
# 匹配后面跟着 .com 的邮箱,但不包含 .com
r"\w+(?=\.com)"
match(r"\w+(?=\.com)", "alice@example.com")  # nothing
match(r"\w+(?=\.com)", "bob@gmail.com")      # nothing
# 正确示例:
s = "alice@example.com"
match(r"\w+(?=\.com)", s)  # RegexMatch("example")

九、实际应用示例

1. 提取所有手机号(中国大陆)

text = """
联系人:张三,电话:138-1234-5678
李四:13912345678
王五:+86 136 9876 5432
"""

pattern = r"1[3-9]\d{9}|1[3-9]\d{2}-\d{4}-\d{4}"
phones = [m.match for m in eachmatch(pattern, text)]
# → ["138-1234-5678", "13912345678", "13698765432"]

2. 解析日志时间戳

log = "[2025-10-26 14:30:22] ERROR: Connection failed"

r = r"\[(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}:\d{2}:\d{2})\] (?<level>\w+): (?<msg>.*)"
m = match(r, log)
m[:date]   # "2025-10-26"
m[:time]   # "14:30:22"
m[:level]  # "ERROR"
m[:msg]    # "Connection failed"

3. 清理 HTML 标签

html = "<p>Hello <b>World</b>!</p>"
clean = replace(html, r"<[^>]*>" => "")
# → "Hello World!"

十、正则表达式速查表

模式含义
.任意字符
^行首
$行尾
*0次或多次
+1次或多次
?0次或1次
{n,m}n到m次
[abc]a或b或c
[^abc]非a/b/c
\d数字
\w单词字符
\s空白
(abc)分组
(?<name>abc)命名分组
a|ba或b
(?=abc)正向前瞻

十一、性能建议

建议说明
提前编译正则const EMAIL_REGEX = r"..."
避免过度嵌套复杂正则变慢
occursin 快速判断match
大文本用 eachmatch 流式处理节省内存
const PHONE_REGEX = r"1[3-9]\d{9}"

function is_valid_phone(s)
    occursin(PHONE_REGEX, s)
end

十二、小练习(立即上手)

  1. 匹配 IPv4 地址(如 192.168.1.1
  2. 提取 URL 中的协议、域名、路径
  3. 2025-10-26 转为 2025年10月26日
  4. 匹配连续重复的单词(如 “the the”)
  5. 实现 split 函数(用正则)

答案示例

# 1. IPv4
ipv4 = r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$"
# 验证:all(x -> 0 ≤ parse(Int,x) ≤ 255, m.captures)

# 2. URL 解析
url = r"(?<protocol>https?)://(?<host>[^/]+)(?<path>/.*)?"
m = match(url, "https://example.com/path/to/file")
m[:protocol], m[:host], m[:path]

# 3. 日期格式化
date = "2025-10-26"
replace(date, r"(\d{4})-(\d{2})-(\d{2})" => s"\1年\2月\3日")

# 4. 重复单词
text = "this this is a a test"

[m.match for m in eachmatch(r”\b(\w+)\s+\1\b”i, text)]

# → [“this this”, “a a”] # 5. 正则 split mysplit(s, delim) = [m.match for m in eachmatch(Regex(“.*?$delim”), s)][1:end-1]


十三、调试工具

using RegexTools  # 可选包:可视化正则
# 或在线:https://regex101.com (选择 PCRE)

恭喜!你已精通 Julia 正则表达式!

现在你可以:

  • 轻松解析日志、CSV、HTML
  • 实现数据清洗、验证
  • 写出高效文本处理管道
  • 构建配置解析器、爬虫

下一站推荐

主题为什么学
CSV.jl真实数据导入
HTTP.jl + 正则网页爬取
DataFrames数据清洗
Parsers.jl高性能解析
TextAnalysis.jlNLP 基础

需要我:

  • 写一个 日志分析器(提取时间、级别、消息)?
  • 实现 配置文件解析器(.ini / .toml 风格)?
  • 构建 邮箱验证 + 提取工具
  • 生成 正则表达式思维导图

随时告诉我!

文章已创建 2305

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部