在易语言的世界里处理文本,尤其是从复杂的字符串中精准地抓取你想要的那段内容,就好比在满桌子的零件里找出特定型号的螺丝钉。手动处理?费时费力还容易出错。这时候,
正则表达式
这位“模式匹配大师”就该登场了。它就像一个极其灵活的搜索框,能按照你定义的规则,从一堆杂乱无章的文本中,把你需要的部分“勾”出来。
很多易语言的伙伴对正则既好奇又有点怵,觉得它语法复杂、难以驾驭。其实,一旦掌握了几个核心技巧,并通过实际案例拆解,你会发现它在易语言中的应用可以非常直观和高效。今天,我们就抛开那些生硬的概念堆砌,直接进入“实战厨房”,看看如何用易语言和正则表达式这把“瑞士军刀”,优雅地解决提取子串的各种难题。
一、 准备工作:在易语言中召唤“正则助手”
在易语言中使用正则,第一步是创建正则表达式对象。这就像请出一位专家,你得先跟它打个招呼(创建对象),告诉它你的需求(设置模式),然后它才会开始工作。
.版本 2
.支持库 reg
.程序集 窗口程序集_启动窗口
.程序集变量 正则对象, 正则表达式类
.子程序 __启动窗口_创建完毕
‘ 第一步:创建正则表达式对象
正则对象 = (#正则表达式类).创建 ()
‘ 创建成功后,我们就可以开始设置匹配规则了
二、 核心技巧:配置你的“捕捞网”
创建对象后,最核心的就是配置“模式字符串”。这个字符串定义了你要匹配的文本格式。我们来认识几个最常用、也最强大的“渔网结”。
1. 普通字符与“元字符”:最基本的渔网线
普通字符(如
a-z
,
0-9
,
#
)就是用来匹配它们自身的。而元字符(如
.
,
*
,
+
,
?
,
^
,
$
,
[
,
]
,
()
,
|
,
\
)则赋予了正则强大的描述能力。
.
(点)
:匹配除换行符以外的任意单个字符。比如
a.c
可以匹配
abc
,
a1c
,
a@c
。
\d
:匹配任意一个数字,等价于
[0-9]
。
\w
:匹配任意一个字母、数字或下划线,等价于
[a-zA-Z0-9_]
。
\s
:匹配任意一个空白字符(空格、制表符等)。
\
(反斜杠)
:转义字符。用来“解锁”一个元字符的字面意思。比如要匹配一个点本身,就要写
\.
。
2. 量词:控制重复次数的“节拍器”
*
:匹配前面的子表达式零次或多次(越长越好)。
+
:匹配前面的子表达式一次或多次(至少一次)。
?
:匹配前面的子表达式零次或一次(可有可无)。
{n}
:精确匹配n次。比如
\d{4}
匹配正好4个数字。
{n,}
:至少匹配n次。
*?
,
+?
,
??
:这些是
非贪婪匹配
模式,非常重要!默认量词是贪婪的,会尽可能多地匹配。加上
?
后,会尽可能少地匹配,直到满足整体模式。这在提取HTML标签等内容时至关重要。
3. 位置锚点:精准定位的“GPS”
^
:匹配字符串的开始位置。
$
:匹配字符串的结束位置。
^
和
$
连用
:可以确保整个字符串完全符合模式,没有多余内容。例如
^\d{11}$
只能匹配正好是11位数字的字符串。
4. 分组与捕获:“抓取器”的核心
这是提取子串的灵魂所在!用圆括号
()
把你要提取的部分括起来,这些被括起来的部分就称为一个“捕获组”。
模式:`(\d{4})-(\d{2})-(\d{2})`
文本:`我的生日是1990-05-20,今天是2023-10-17`
这个模式会匹配日期格式,其中:
组0(整个匹配)
:
1990-05-20
或
2023-10-17
组1(第一个括号)
:
1990
或
2023
(年份)
组2(第二个括号)
:
05
或
10
(月份)
组3(第三个括号)
:
20
或
17
(日)
5. 分支:“或”逻辑的开关
竖线
|
表示“或”的关系,就像
cat|dog
会匹配
cat
或者
dog
。可以用在分组里,如
(http|https)
匹配
http
或
https
。
三、 实战演练:案例拆解与代码解析
技巧讲了,关键在于用。我们来看几个真实场景。
案例一:从一堆文字中提取所有手机号码
手机号的常见模式:1开头,11位数字。我们可以使用
\b1[3-9]\d{9}\b
。
\b
:单词边界,确保我们提取的是完整的11位号码,而不是某个更长数字的一部分(比如身份证号里的一段)。
1
:第一位是1。
[3-9]
:第二位是3到9之间的任意数字(涵盖了目前所有运营商号段)。
\d{9}
:后面是9个任意数字。
.版本 2
.支持库 reg
.子程序 提取手机号
.参数 原始文本, 文本型
.局部变量 正则, 正则表达式类
.局部变量 匹配结果, 匹配结果类
.局部变量 所有号码, 文本型
正则 = (#正则表达式类).创建 ()
正则.模式 = “\b1[3-9]\d{9}\b”
正则.全局匹配 = 真 ‘ 关键!设为“真”才能找出所有匹配项
正则.忽略大小写 = 假
匹配结果 = 正则.匹配 (原始文本)
如果 (匹配结果.取匹配数 () > 0) ‘ 检查是否找到了匹配
.计次循环首 (匹配结果.取匹配数 (), 1)
所有号码 = 所有号码 + 匹配结果.取子匹配文本 (1, 0) + #换行符 ‘ 子匹配索引0代表整个匹配
.计次循环尾 ()
返回 (所有号码)
小贴士
:
全局匹配
属性是找出“所有”还是“第一个”的关键开关。对于提取列表类的数据,必须设为真。
案例二:从URL中提取域名和路径
假设我们有链接
http://www.example.com:8080/path/to/page.html?user=admin#section1
,想提取
www.example.com
和
/path/to/page.html
。
模式可以设计为:
(https?://)?([^:/]+)(:\d+)?(/\S*)?
(https?://)?
:可选的协议头,
http
或
https
。
([^:/]+)
:捕获组,匹配域名。规则是不包含
:
和
/
的字符序列。这是我们要的域名部分。
(:\d+)?
:可选的端口号。
(/\S*)?
:捕获组,匹配路径。以
/
开头,后面跟非空白字符。这是我们要的路径。
.子程序 提取URL信息
.参数 URL地址, 文本型
.局部变量 正则, 正则表达式类
.局部变量 匹配结果, 匹配结果类
.局部变量 域名, 文本型
.局部变量 路径, 文本型
正则 = (#正则表达式类).创建 ()
‘ 模式字符串中,第二个和第四个括号是我们要的捕获组
正则.模式 = “(https?://)?([^:/]+)(:\d+)?(/\S*)?”
匹配结果 = 正则.匹配 (URL地址)
如果 (匹配结果.取匹配数 () > 0) ‘ 确保至少有匹配
域名 = 匹配结果.取子匹配文本 (1, 2) ‘ 取第一个匹配的第二个捕获组
路径 = 匹配结果.取子匹配文本 (1, 4) ‘ 取第一个匹配的第四个捕获组
信息输出 (“域名:” + 域名 + #换行符 + “路径:” + 路径)
案例三:提取HTML标签内的文本(非贪婪匹配的应用)
这是一个经典难题。如果我们想提取
中的“你好,易语言!”,一个
错误
的模式是
。
因为
.*
是贪婪的,它会从第一个
最后一个
,中间所有内容都会被吞掉,这显然不是我们要的。
正确的方法
是使用
非贪婪匹配
.*?
,或者更精确地指定内容类型。
错误模式:
→ 贪婪,匹配整个从头到尾的HTML块。
正确模式1
:
→ 非贪婪,会匹配最短的、以