1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Matlab 正则表达式

Matlab 正则表达式

时间:2022-04-03 07:16:08

相关推荐

Matlab 正则表达式

Matlab 正则表达式

1 引言2 单个字符匹配2.1 元字符2.2 特殊字符 3 字符串匹配3.1 多次匹配3.2 零宽断言/环顾断言(左顾右盼)——利用上下文匹配3.3 逻辑条件匹配 4 标记(tokens)匹配5 动态正则表达式6 搜索标志7 多行字符串与多正则表达式7.1 多字符串与单个正则表达式匹配7.2 多个字符串与多个正则表达式匹配7.3 多字符串的替换 8 结语参考文献

使用Matlab处理字符串及文本时,需要与 正则表达式打交道。 正则表达式是一个非常重要的编程概念,主流的编程语言都对正则表达式进行了很好的支持,Matlab也不例外。

本期推文就让我们来总结一下Matlab提供的正则表达式吧!

1 引言

正则表达式(Regular Expression),又称规则表达式,本质上是一串字符,它定义了某种字符串模式,通常被用来检索、替换那些符合某个模式(规则)的文本。

Matlab 提供的正则表达式库函数主要有三个:

(1) regexp—用于对字符串进行查找,大小写敏感;

(2) regexpi—用于对字符串进行查找,大小写不敏感;

(3) regexprep—用于对字符串进行查找并替换。

下面主要介绍一下 regexp 这个函数的主要用法:

用法1:

[startIndex, endIndex] = regexp(str, expression)返回所有匹配项的开始和结束索引。

用法2:

out = regexp(str, expression, outkey)返回outkey指定的输出。例如,如果outkey'match',则regexp返回与该表达式匹配的子字符串而非其开始索引。outkey通常的取值有:

用法3:

[out1, ..., outN] = regexp(str, expression, outkey1, ..., outkeyN)按指定的顺序返回多个输出关键字指定的输出。例如,如果指定matchtokens,则 regexp 返回与整个表达式匹配的子字符串以及与部分表达式匹配的标文。

用法4:

___ = regexp(___, option1, ..., optionM)使用指定的选项标志修改搜索。例如,指定 ‘ignorecase’ 以执行不区分大小写的匹配。可以包括任何输入并请求之前语法中的任何输出。

用法5:

___ = regexp(___, 'forceCellOutput')以标量元胞的形式返回每个输出参数。元胞包含被描述为上述语法输出的数值数组或子字符串。可以包括任何输入并请求之前语法中的任何输出。

2 单个字符匹配

正则表达式,指定为字符向量、字符向量元胞数组或字符串数组。

每个表达式可包含字符、元字符、运算符、标文和用于指定在 str 中匹配的模式的标志。

2.1 元字符

元字符表示字母、字母范围、数字和空格字符。使用它们来构造广义的字符模式。

. 匹配任何单个字符,包括空格和换行符。例..ain与以ain结尾的五个连续字符序列匹配。

[] 匹配括号内的任意字符,$,|,.,*,+,?,-这些字符按字面匹配。例[rp.]ain'rainpain.ain'匹配。

[^] 匹配除括号内字符的其它任意字符。例[^*rp]ain与以ain结尾的所有由四个字母组成的序列(rainpain'*ain除外)匹配。如,它与gainlainvain匹配。

[a-b] 匹配a-b范围中的任意字符,如[a-z],A-Z,[0-9],A-y,[10-99]

\w 匹配任意英文字母、数字、下划线,等价于[a-z_A-Z0-9][a-zA-Z_0-9]。例\w*标识一个单词。

\W 匹配任意非英文字母、数字、下划线,等价于[^a-zA-Z_0-9]。例\W*标识非单词项。

\s 匹配任意非空白(空格)字符,等价于[\f\n\r\t\v]。 如\w*n\s与以字母 n 结尾且后跟空白字符的单词匹配。

注: 字符表示

\S 匹配任意非空白字符,等价于[^ \f\n\r\t\v]。例\d\S与数字(后跟任意非空白字符)匹配。

\d 匹配任意数字,等价于[0-9]。例\d*与任意数量的连续数字匹配。

\D 匹配任意非数字,等价于[^0-9]。例\w*\D\>与不以数字结尾的单词匹配。

oN或\o{N} 匹配八进制数N对应的Unicode字符。例\o{40}与八进制40定义的空格字符匹配。

xN或\x{N} 匹配十六进制数N对应的Unicode字符。例\x2C与十六进制2C定义的逗号字符匹配,[\x4e00-\x9fa5]匹配任意汉字。

2.2 特殊字符

\char 匹配表达式中的特殊字符,进行转义。$^*()+={}<>|.\?-。这些特殊字符前边加上\将会对其转义,使得匹配他们的字面值。

3 字符串匹配

3.1 多次匹配

元字符及其特殊字符的匹配,每次只能匹配一个字符,如果需要匹配多个字符,即字符串的匹配,那么就要重复好几次元字符的表达式。

比如,匹配mmm,那么就可以用正则表达式mmm, 但还有一种更简单的表示法m{3}。其中{}表示匹配前面的表达式出现的次数,称为限定符,m{2, 3}匹配mmmmm

除了{}限定符,还有其他常用的一些限定符,描述如下:

expr* 与expr匹配的元素出现0更多次,相当于{0, }。例\w*与任意长度的单词匹配。

expr? 与expr匹配的元素出现01次,相当于{0, 1}。例\w*(\.m)?与单词或以扩展名 .m 结尾(此条件为可选条件)的单词匹配。

expr+ 与expr匹配的元素出现1更多次,相当于{1, }。例<img src="\w+\.gif">与 HTML 标记匹配(当文件名包含一个或多个字符时)。

expr{n} 与expr匹配的元素出现n次,相当于{n, n}。 例\d{4}与四个连续数字匹配。

expr{n, m} 与expr匹配的元素至少出现n次但不多于m次 。例\S{4,8}与四到八个非空白字符匹配。

expr{n, } 与expr匹配的元素至少出现n次。 例<a href="\w{1,}\.html">'与 HTML 标记匹配(当文件名包含一个或多个字符时)。

假设我们要在文本中搜索美国的社会安全号码,号码的格式是000-00-0000,那么匹配它的正则表达式可以写为\d{3}\-\d{2}\-\d{4}。 注意到-是特殊字符,所以用\-进行了转义。

如果希望字符号码连续出现,如000000000,也可以不出现,即000-00-0000。上面两种形式都属于正确的格式,这时可以在字符-后面加上数量限定符?,因此表达式可改写为\d{3}\-?\d{2}\-?\d{4}\-?

另外,当我们使用expr*时,Matlab 将尽可能的匹配最长的字符字串,如

s = '<tr valign=top><td><a name="19184"></a>xyz';regexp(s, '<.*>', 'match')

输出:

{'<tr valign=top><td><a name="19184"></a>'}

如果我们希望匹配尽可能短的字符字串时,可以在上面使用的表达式后加个?, 即.*?,如

s = '<tr valign=top><td><a name="19184"></a>xyz';regexp(s, '<.*?>', 'match')

输出:

{'<tr valign=top>'} {'<td>'} {'<a name="19184">'} {'</a>'}

上面的例子说明了对限定符的一种显示模式之一。

下面具体说明限定符的三种模式——限定修饰符,简单起见,用q表示上述6个限定符中的任意一个。

exprq积极表达式:与尽可能多的字符匹配。如给定文本<tr><td><p>text</p></td>,表达式</?t.*>匹配介于 <tr 和 /td> 之间的所有字符。

exprq?消极表达式:与所需的尽可能少的字符匹配。如文本<tr><td><p>text</p></td>,表达式</?t.*?>在第一次出现右尖括号 (>) 时结束每个匹配项:{'<tr>'} {'<td>'} {'</td>'}

exprq+主动表达式:最大程度地匹配,但不重新扫描文本的任何部分。如给定文本<tr><td><p>text</p></td>,表达式</?t.*+>不返回任何匹配项,这是因为右尖括号是使用 .* 捕获的且不进行重新扫描。

3.2 零宽断言/环顾断言(左顾右盼)——利用上下文匹配

利用上下文匹配可以说非常常用,比如想要提取一段文本中特定的部分内容,那么零宽断言就非常适合干这类事情。

零宽断言查找紧邻预期匹配项前后但并非该匹配项一部分的模式。

指针停留在当前位置,并且将放弃或不捕获对应于 test 表达式的字符。因此,前向断言可匹配重叠字符组。

在介绍零宽断言之前,先介绍下定位点。表达式中的定位点与文本或单词的开头或结尾匹配。

^expr 匹配以expr开头的字符串。如^M\w*与以 M 作为文本开头的单词匹配。expr$ 匹配以expr结尾的字符串。如 '\w*m$’ 与以 m 作为文本结尾的单词匹配。\<expr 匹配以expr开头的英文单词。如\<n\w*与以 n 开头的任何单词匹配。expr\> 匹配以expr结尾的英文单词。如\w*e\>与以 e 结尾的任何单词匹配。

回过头来,下面我们介绍零宽断言

expr(?=test) 先行断言:向前查找与test匹配的字符。即匹配后面跟的字符是test的字符。如\w*(?=ing)匹配后跟 ing 的词汇,匹配输入文本Flying, not falling.中的Flyfall。特殊情况:expr(?=$)等价于expr$expr(?=\>)等价于expr\>

expr(?!test) 负向先行断言:向前查找与test不匹配的字符。即匹配后面跟的字符不是test的字符。如i(?!ng)匹配字母 i 的后面不跟 ng 的字符。

(?<=test)expr 后发断言:向后查找与 test 匹配的字符。即匹配前面的字符有test的字符。如(?<=re)\w*匹配紧跟re的词汇,例如输入文本renew, reuse, recycle中的newusecycle。特殊情况:(?<=^)expr等价于^expr(?<=\<)expr等价于\<expr

(?<!test)expr 负向后发断言:向后查找与 test 不匹配的字符。即匹配前面的字符没有test的字符。如(?<!\d)(\d)(?!\d)与一位数字匹配(不紧随其他数字前后的数字)。

实际应用中,可以通过组合上面4中断言进行文本内容的提取,比如我们想要提取'<a href="">'文本中的网址,那么可以同时使用先行和后发断言,“左顾右盼”来提取网址内容:

s = '<a href="">';regexp(s, '(?<=<a href=").*?(?=">)', 'match')

输出:

{''}

3.3 逻辑条件匹配

如果我们在表达式之前指定先行断言,即(?=test)expr等,则运算等同于逻辑 AND。这一点比较容易混淆。

(?=test)expr 同时与testexpr匹配。如(?=[a-z])[^aeiou]与辅音匹配。(?!test)expr 匹配expr,但不匹配test。如(?![aeiou])[a-z]与辅音匹配。

逻辑和条件运算符允许我们测试给定条件的状态,然后使用结果确定哪个模式(如果有)与下一条件匹配。这些运算符支持逻辑ORifif/else条件。

条件可以是标文、环顾运算符或 (?@cmd) 形式的动态表达式。动态表达式必须返回逻辑值或数值。

条件运算法:

expr1 | expr2 匹配表达式expr1或表达式expr2。比如(let|tel)\w+匹配以 let 或 tel 开头的单词。

(?(cond)expr) 如果条件condtrue,则匹配expr。如(?(?@ispc)[A-Z]:\\)匹配驱动器名称,例如 C:\(在 Windows® 系统上运行时)。

(?(cond)expr1 | expr2) 如果条件condtrue,则匹配expr1。否则,匹配expr2。如Mr(s?)\..*?(?(1)her|his) \w*匹配包含 her 的文本(当文本以 Mrs 开头时),或包含 his 的文本(当文本以 Mr 开头时)。

4 标记(tokens)匹配

标记这部分是较难的一部分,但是使用得当可以实现非常强大的功能。

任何的正则表达式都可以用圆括号括起来作为一个标记。可以按标记在文本中的顺序引用该标记(顺序标记),或将名称分配给标记以便于代码维护和使输出更易于阅读。

(expr) 匹配expr并创建标记。如Joh?n\s(\w*)捕获一个标记,该标记包含名字为 John 或 Jon 的任何人的姓氏。(?:expr) 匹配expr,不创建标记。(?>expr) 匹配expr,不创建标记,不回溯扫描。(expr1|expr2) 匹配expr1或者expr2,创建标记。\N 匹配第N个标记,N从1开始。如<(\w+).*>.*</\1>从文本<title>Some text</title>捕获 HTML 标记的标文,例如title。(?(N)expr1|expr2) 如果找到第 N 个标文,则匹配expr1。否则,匹配expr2。如Mr(s?)\..*?(?(1)her|his) \w*匹配包含her的文本(当文本以Mrs开头时),或包含his的文本(当文本以Mr开头时)。(?expr) 匹配expr并创建命名为name的标记。(?<month>\d+)-(?<day>\d+)-(?<yr>\d+)mm-dd-yy形式的输入日期中创建命名月、日和年标记。\k 匹配名为name的标记。<(?<tag>\w+).*>.*</\k<tag>>从文本<title>Some text</title>捕获 HTML 标记的标文,例如title。(?(name)expr1|expr2) 若存在名为name的标记,则匹配expr1,否则匹配expr2。如Mr(?<sex>s?)\..*?(?(sex)her|his) \w*匹配包含her的文本(当文本以Mrs开头时),或包含his的文本(当文本以 Mr 开头时)。

5 动态正则表达式

动态表达式允许我们执行 MATLAB 命令或正则表达式以确定要匹配的文本。

将动态表达式括起来的括号创建捕获组。

(??expr) 解析expr并将得到的项包括在匹配表达式中。解析后,expr必须对应于完整的有效正则表达式。使用反斜杠转义字符(\)的动态表达式需要两个反斜杠:一个用于expr的初始解析,一个用于完整匹配。如^(\d+)((??\\w{$1}))通过读取匹配项开头的数字确定匹配的字符数。(\w\W\d\D\s\S,和\char这些在动态表达式中需要再加个\)。动态表达式括在另一组括号中,以便在标记中捕获生成的匹配项。例如,匹配5XXXXX将捕获5XXXXX的标文。(??@cmd) 执行cmd表示的 MATLAB 命令,并将该命令返回的输出包括在匹配表达式中。(.{2,}).?(??@fliplr($1))查找长度至少为四个字符的回文,例如abba。(?@cmd) 执行cmd表示的 MATLAB 命令,但放弃该命令返回的任何输出。(对诊断正则表达式有帮助。)\w*?(\w)(?@disp($1))\1\w*匹配包括双字母(例如 pp)的单词并显示中间结果。

在动态表达式中,使用下列运算符定义替代文本。

注释:

(?#comment) 在正则表达式中插入注释。匹配输入时将忽略注释文本。如(?# Initial digit)\<\d\w+包括一个注释,并匹配以一个数字开头的单词。

6 搜索标志

搜索标志修改匹配表达式的行为。在表达式中使用搜索标志的替代方法是传递 option 输入参数。

该标志修改的表达式可显示在括号后,例如

(?i)\w*

或显示在括号内并使用冒号 (😃 与该标志分隔开,例如

(?i:\w*)

7 多行字符串与多正则表达式

7.1 多字符串与单个正则表达式匹配

多个字符串存在一个元胞数组里之后,每一个字符串与正则表达式匹配,返回值的维数与元胞数组的维数相同。

s = {'letter'; 'tell'; 'lethal'; 'television'; 'other'};regexp(s, '(let|tel)\w+', 'match')

输出:

5x1的cell。

7.2 多个字符串与多个正则表达式匹配

这种情况下,应该满足字符串元胞数组中字符串的个数和正则表达式的个数相等,但维数不一定要相等。

如可以用5x1的元胞数组与1x4的正则表达式相匹配。

s = {'letter'; 'tell'; 'lethal'; 'television'; 'other'};expr = {'^t\w+?', '\w+r?$', '\<le\w+?', '\w+er\>?', 'l.*r?'};regexp(s, expr, 'match')

7.3 多字符串的替换

这个功能是在匹配的基础上,在表达式后面加入要替换的字符串即可。

s = {'letter'; 'tell'; 'lethal'; 'television'; 'other'};s1 = regexprep(s, '(.)\1', '**', 'ignorecase');

输出:

8 结语

使用正则表达式的过程中,如果是每天与它打交道,也就很容易记住这些规则,孰能生巧,然而长时间不使用正则表达式,就会渐渐的生疏。

因此推文总结了正则表达式常用的用法和一些相关示例说明,没事干的时候就刷一刷,帮助记忆、理解。同时,希望能够帮助有相同需要的朋友。

参考文献

匹配正则表达式(区分大小写) - MATLAB regexp - MathWorks 中国

Matlab的正则表达式:字符串及文本处理的利器(上)

Matlab的正则表达式:字符串及文本处理的利器(下)

Luo H . MATLAB GUI设计学习手记 (第3版)[J]. .

本文首发于 微信公众号:清贫王子

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。