文档gydF4y2Ba

动态正则表达式gydF4y2Ba

简介gydF4y2Ba

在动态表达式中,您可以创建所需的模式gydF4y2Ba正则表达式gydF4y2Ba根据输入文本的内容进行匹配。通过这种方式,您可以更紧密地匹配正在解析的文本中的各种输入模式。的替换术语中也可以使用动态表达式gydF4y2BaregexprepgydF4y2Ba函数。这使您能够根据解析后的输入调整替换文本。gydF4y2Ba

控件中可以包含任意数量的动态表达式gydF4y2Bamatch_exprgydF4y2Ba或gydF4y2Bareplace_exprgydF4y2Ba这些命令的参数:gydF4y2Ba

regexpi(text, match_expr) regexprep(text, match_expr, replace_expr)gydF4y2Ba

下面是动态表达式的一个示例gydF4y2BaregexprepgydF4y2Ba命令正确替换术语gydF4y2Ba国际化gydF4y2Ba用它的缩写形式,gydF4y2Bai18ngydF4y2Ba.然而,要用在不同的术语上,比如gydF4y2Ba全球化gydF4y2Ba,你必须使用一个不同的替换表达式:gydF4y2Ba

match_expr =gydF4y2Ba”(^ \ w) (\ w *) (\ w)美元的gydF4y2Ba;replace_expr1 =gydF4y2Ba“118美元3美元”gydF4y2Ba;regexprep (gydF4y2Ba“国际化”gydF4y2Ba, match_expr, replace_expr1)gydF4y2Ba
Ans = 'i18n'gydF4y2Ba
replace_expr2 =gydF4y2Ba“111美元3美元”gydF4y2Ba;regexprep (gydF4y2Ba“全球化”gydF4y2Ba, match_expr, replace_expr2)gydF4y2Ba
Ans = 'g11n'gydF4y2Ba

使用动态表达式gydF4y2Ba$ {num2str(长度(2美元))}gydF4y2Ba使您能够将替换表达式建立在输入文本的基础上,这样就不必每次都更改表达式。这个例子使用了动态替换语法gydF4y2Ba$ {cmd}gydF4y2Ba.gydF4y2Ba

match_expr =gydF4y2Ba”(^ \ w) (\ w *) (\ w)美元的gydF4y2Ba;replace_expr =gydF4y2Ba' $ 1 $ {num2str(长度(2美元))}3美元的gydF4y2Ba;regexprep (gydF4y2Ba“国际化”gydF4y2Ba, match_expr, replace_expr)gydF4y2Ba
Ans = 'i18n'gydF4y2Ba
regexprep (gydF4y2Ba“全球化”gydF4y2Ba, match_expr, replace_expr)gydF4y2Ba
Ans = 'g11n'gydF4y2Ba

解析时,动态表达式必须对应一个完整的、有效的正则表达式。此外,使用反斜杠转义字符(gydF4y2Ba\gydF4y2Ba)需要两个反斜杠:一个用于表达式的初始解析,另一个用于完全匹配。包含动态表达式的括号是这样的gydF4y2Ba不gydF4y2Ba创建捕获组。gydF4y2Ba

您可以在匹配表达式中使用三种形式的动态表达式,在替换表达式中使用一种形式,如下面的部分所述gydF4y2Ba

动态匹配表达式- (??expr)gydF4y2Ba

的gydF4y2Ba(? ? expr)gydF4y2Ba运算符解析表达式gydF4y2BaexprgydF4y2Ba,并将结果插入到匹配表达式中。MATLABgydF4y2Ba®gydF4y2Ba然后计算修改后的匹配表达式。gydF4y2Ba

下面是一个可以与该操作符一起使用的表达式类型的例子:gydF4y2Ba

CHR = {gydF4y2Ba“5 xxxxx”gydF4y2Ba,gydF4y2Ba“8 xxxxxxxx”gydF4y2Ba,gydF4y2Ba“1 x”gydF4y2Ba};正则表达式(空空的,gydF4y2Ba' ^ (\ d +) (? ? X美元{1})的美元gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba,gydF4y2Ba“一次”gydF4y2Ba);gydF4y2Ba

这个特定命令的目的是定位一系列的gydF4y2BaXgydF4y2Ba存储在输入单元格数组中的每个字符向量中的字符。请注意gydF4y2BaXgydF4y2BaS在每个字符向量中都是不同的。如果计数不变,则可以使用表达式gydF4y2BaX {n}gydF4y2Ba表示您想要匹配gydF4y2BangydF4y2Ba这些人物。但是,一个常数值gydF4y2BangydF4y2Ba在这种情况下是行不通的。gydF4y2Ba

这里使用的解决方案是捕获前导计数数(例如gydF4y2Ba5gydF4y2Ba),然后在动态表达式中使用该计数。本例中的动态表达式为gydF4y2Ba(? ? X美元{1})gydF4y2Ba,在那里gydF4y2Ba1美元gydF4y2Ba令牌是否捕获了值gydF4y2Ba\ d +gydF4y2Ba.操作员gydF4y2Ba{$ 1}gydF4y2Ba生成该令牌值的量词。因为表达式是动态的,所以相同的模式适用于单元格数组中的所有三个输入向量。对于第一个输入字符向量,gydF4y2Ba正则表达式gydF4y2Ba寻找5个gydF4y2BaXgydF4y2Ba字符;对于第二个,它寻找8个,而对于第三个,它只寻找1个:gydF4y2Ba

正则表达式(空空的,gydF4y2Ba' ^ (\ d +) (? ? X美元{1})的美元gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba,gydF4y2Ba“一次”gydF4y2Ba)gydF4y2Ba
ans = 1×3 cell array {'5XXXXX'} {'8XXXXXXXX'} {'1X'}gydF4y2Ba

修改匹配表达式的命令- (??@cmd)gydF4y2Ba

MATLAB使用gydF4y2Ba(? ? @cmd)gydF4y2Ba运算符将MATLAB命令的结果包含在匹配表达式中。该命令必须返回一个可以在匹配表达式中使用的术语。gydF4y2Ba

例如,使用动态表达式gydF4y2Ba(? ? @flilplr(1美元))gydF4y2Ba来定位一个回文,“Never Odd or Even”,它被嵌入到一个更大的字符向量中。gydF4y2Ba

首先,创建输入字符串。确保所有字母都是小写的,并删除所有非单词字符。gydF4y2Ba

低(gydF4y2Ba...gydF4y2Ba'在此字符串中查找从不奇数或偶数的回文'gydF4y2Ba);CHR = regexprep(CHR,gydF4y2Ba“\ W *”gydF4y2Ba,gydF4y2Ba”gydF4y2Ba)gydF4y2Ba
CHR = 'findthepalindromeneveroddoreveninthisstring'gydF4y2Ba

使用动态表达式在字符向量中定位回文:gydF4y2Ba

回文= regexp(chr,gydF4y2Ba”({3})? (? ? @fliplr(1美元))”gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba)gydF4y2Ba
回文= 1×1 cell array {'neveroddoreven'}gydF4y2Ba

动态表达式将组成字符向量的字母顺序颠倒,然后尝试尽可能多地匹配颠倒顺序的向量。这需要一个动态表达式,因为for的值gydF4y2Ba1美元gydF4y2Ba取决于令牌的值gydF4y2Ba({3})。gydF4y2Ba.gydF4y2Ba

MATLAB中的动态表达式可以访问当前活动工作区。这意味着您可以通过更改工作空间中的变量来更改动态表达式中使用的任何函数或变量。重复上面例子的最后一个命令,但这一次使用存储在基本工作区中的函数句柄在表达式中定义要调用的函数:gydF4y2Ba

乐趣= @fliplr;回文= regexp(chr,gydF4y2Ba”({3})? (? ? @fun(1美元))”gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba)gydF4y2Ba
回文= 1×1 cell array {'neveroddoreven'}gydF4y2Ba

用于功能目的的命令- (?@cmd)gydF4y2Ba

的gydF4y2Ba(? @cmd)gydF4y2Baoperator指定一个MATLAB命令gydF4y2Ba正则表达式gydF4y2Ba或gydF4y2BaregexprepgydF4y2Ba在解析整个匹配表达式时运行。与MATLAB中的其他动态表达式不同,这个运算符不改变它所使用的表达式的内容。相反,您可以使用这个功能让MATLAB报告它在解析正则表达式内容时所执行的步骤。此功能在诊断正则表达式时非常有用。gydF4y2Ba

下面的示例将一个单词解析为零个或多个字符,后跟两个相同的字符,然后再后跟零个或多个字符:gydF4y2Ba

正则表达式(gydF4y2Ba密西西比州的gydF4y2Ba,gydF4y2Ba“\ w * 1 (\ w) \ \ w *’gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba)gydF4y2Ba
Ans = 1×1单元格数组{'mississippi'}gydF4y2Ba

为了跟踪MATLAB在确定匹配时所采取的确切步骤,该示例插入了一个简短的脚本gydF4y2Ba(? @disp(1美元))gydF4y2Ba,以显示最终构成匹配的字符。因为示例使用贪婪量词,所以MATLAB尝试匹配尽可能多的字符向量。因此,即使MATLAB找到了一个接近字符串开头的匹配,它也会继续寻找更多的匹配,直到它到达字符串的最后。从那里回溯到信件gydF4y2Ba我gydF4y2Ba然后gydF4y2BapgydF4y2Ba下一个gydF4y2BapgydF4y2Ba,在这一点停止,因为匹配最终得到满足:gydF4y2Ba

正则表达式(gydF4y2Ba密西西比州的gydF4y2Ba,gydF4y2Ba' \ w * (\ w) (? @disp(1美元))\ 1 \ w *’gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba)gydF4y2Ba
I pp ans = 1×1 cell array {'mississippi'}gydF4y2Ba

现在再次尝试相同的例子,这次使第一个量词懒惰(gydF4y2Ba*?gydF4y2Ba).同样,MATLAB做了同样的匹配:gydF4y2Ba

正则表达式(gydF4y2Ba密西西比州的gydF4y2Ba,gydF4y2Ba‘\ w * ? (\ w) \ 1 \ w *’gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba)gydF4y2Ba
Ans = 1×1单元格数组{'mississippi'}gydF4y2Ba

但是通过插入一个动态脚本,您可以看到这一次,MATLAB对文本的匹配非常不同。在这种情况下,MATLAB使用它能找到的第一个匹配,甚至不考虑其余的文本:gydF4y2Ba

正则表达式(gydF4y2Ba密西西比州的gydF4y2Ba,gydF4y2Ba‘\ w * ? (\ w) (? @disp(1美元))\ 1 \ w *’gydF4y2Ba,gydF4y2Ba“匹配”gydF4y2Ba)gydF4y2Ba
M I s ans = 1×1 cell array {'mississippi'}gydF4y2Ba

为了演示这种类型的动态表达式有多通用,考虑下一个示例,在MATLAB迭代解析输入文本时逐步组装单元格数组。的gydF4y2Ba(? !)gydF4y2Ba在表达式末尾找到的运算符实际上是一个空的前向运算符,并在每次迭代时强制失败。如果您想跟踪MATLAB解析表达式的步骤,这种强制失败是必要的。gydF4y2Ba

MATLAB在输入文本中进行多次传递,每次都尝试另一种字母组合,看看是否能找到比上次匹配更好的匹配。在没有找到匹配项的任何一遍中,测试的结果是一个空字符向量。动态脚本gydF4y2Ba(? @ if (~ isempty ($ &)))gydF4y2Ba对象中省略空字符向量gydF4y2Ba匹配gydF4y2Ba单元阵列:gydF4y2Ba

匹配= {};Expr = [gydF4y2Ba(欧拉\年代)?(柯西\ s) ?(布尔)? (? @ if (~ isempty($ &)),“gydF4y2Ba...gydF4y2Ba'匹配{结束+ 1}= $ &;结束)(? !)gydF4y2Ba];正则表达式(gydF4y2Ba'欧拉柯西布尔'gydF4y2Ba, expr);匹配gydF4y2Ba
matches = 1×6单元格数组{'欧拉柯西波…'}{'欧拉柯西波'}{'欧拉'}{'柯西波'}{'柯西波'}{'布尔波'}gydF4y2Ba

运营商gydF4y2Ba$ &gydF4y2Ba(或同等内容)gydF4y2Ba0美元gydF4y2Ba),gydF4y2Ba美元的gydF4y2Ba,gydF4y2Ba美元的gydF4y2Ba分别引用输入文本中当前匹配的部分、当前匹配之前的所有字符和当前匹配之后的所有字符。在处理动态表达式时,这些操作符有时很有用,特别是那些使用gydF4y2Ba(? @cmd)gydF4y2Ba操作符。gydF4y2Ba

这个示例解析输入文本查找字母gydF4y2BaggydF4y2Ba.在文本的每一次迭代中,gydF4y2Ba正则表达式gydF4y2Ba将当前字符与gydF4y2BaggydF4y2Ba,如果没有找到,就会进入下一个角色。该示例通过用标记正在解析的当前位置来跟踪文本的扫描进度gydF4y2Ba^gydF4y2Ba的性格。gydF4y2Ba

(gydF4y2Ba美元的gydF4y2Ba而且gydF4y2Ba´美元gydF4y2Ba操作符捕获当前解析位置前面和后面的那部分文本。你需要两个单引号(gydF4y2Ba$ "gydF4y2Ba)表示序列gydF4y2Ba´美元gydF4y2Ba当它出现在文本中。)gydF4y2Ba

空空的=gydF4y2Ba“abcdefghij”gydF4y2Ba;expr =gydF4y2Ba‘(?@disp (sprintf(“开始比赛:[% s ^ % s ]'',$`,$''))) g’gydF4y2Ba;正则表达式(expr空空的,gydF4y2Ba“一次”gydF4y2Ba);gydF4y2Ba
[abcdefghij]开始比赛:[a^bcdefghij]开始比赛:[ab^cdefghij]开始比赛:[abc^defghij]开始比赛:[abcd^efghij]开始比赛:[abcde^fghij]开始比赛:[abcdef^ghij]gydF4y2Ba

替换表达式中的命令- ${cmd}gydF4y2Ba

的gydF4y2Ba$ {cmd}gydF4y2Ba操作符修改正则表达式替换模式的内容,使该模式能够适应输入文本中的参数,这些参数可能在每次使用时都有所不同。与MATLAB中使用的其他动态表达式一样,您可以在整个替换表达式中包含任意数量的这些表达式。gydF4y2Ba

在gydF4y2BaregexprepgydF4y2Ba调用,替换模式是gydF4y2Ba“$ {convertMe($ 1、$ 2)}”gydF4y2Ba.在这种情况下,整个替换模式是一个动态表达式:gydF4y2Ba

regexprep (gydF4y2Ba“这条高速公路有125英里长”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba”(\ d + \ ? \ d *) \ W (\ W +) 'gydF4y2Ba,gydF4y2Ba“$ {convertMe($ 1、$ 2)}”gydF4y2Ba);gydF4y2Ba

动态表达式告诉MATLAB执行一个名为gydF4y2BaconvertMegydF4y2Ba使用这两个令牌gydF4y2Ba(\ d + \ ? \ d *)gydF4y2Ba而且gydF4y2Ba(\ w +)gydF4y2Ba,从被匹配的文本派生,作为调用中的输入参数gydF4y2BaconvertMegydF4y2Ba.替换模式需要动态表达式,因为的值gydF4y2Ba1美元gydF4y2Ba而且gydF4y2Ba2美元gydF4y2Ba在运行时生成。gydF4y2Ba

下面的示例定义文件名gydF4y2BaconvertMegydF4y2Ba它将单位从英制单位转换为公制单位。gydF4y2Ba

函数gydF4y2Bavalout = convertMe(valin,单位)gydF4y2Ba开关gydF4y2Ba(单位)gydF4y2Ba情况下gydF4y2Ba“英寸”gydF4y2Ba乐趣= @(in)in .* 2.54;uout =gydF4y2Ba“厘米”gydF4y2Ba;gydF4y2Ba情况下gydF4y2Ba“英里”gydF4y2Ba乐趣= @(mi)mi .* 1.6093;uout =gydF4y2Ba“公里”gydF4y2Ba;gydF4y2Ba情况下gydF4y2Ba“英镑”gydF4y2Ba乐趣= @(lb)lb .* 0.4536;uout =gydF4y2Ba“公斤”gydF4y2Ba;gydF4y2Ba情况下gydF4y2Ba“品脱”gydF4y2Ba乐趣= @(pt)pt .* 0.4731;uout =gydF4y2Ba“升”gydF4y2Ba;gydF4y2Ba情况下gydF4y2Ba“盎司”gydF4y2Ba乐趣= @(oz)oz .* 28.35;uout =gydF4y2Ba“克”gydF4y2Ba;gydF4y2Ba结束gydF4y2BaVal = fun(str2num(valin));Valout = [num2str(val)]gydF4y2Ba' 'gydF4y2Bauout];gydF4y2Ba结束gydF4y2Ba

在命令行上调用gydF4y2BaconvertMegydF4y2Ba函数gydF4y2BaregexprepgydF4y2Ba,传入要转换的量的值和单位名称:gydF4y2Ba

regexprep (gydF4y2Ba“这条高速公路有125英里长”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba”(\ d + \ ? \ d *) \ W (\ W +) 'gydF4y2Ba,gydF4y2Ba“$ {convertMe($ 1、$ 2)}”gydF4y2Ba)gydF4y2Ba
ans =“这条高速公路长201.1625公里”gydF4y2Ba
regexprep (gydF4y2Ba“这个水罐能装2.5品脱水”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba”(\ d + \ ? \ d *) \ W (\ W +) 'gydF4y2Ba,gydF4y2Ba“$ {convertMe($ 1、$ 2)}”gydF4y2Ba)gydF4y2Ba
ans =“这个水罐能装1.1828升水”gydF4y2Ba
regexprep (gydF4y2Ba“这块石头重约10磅”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba”(\ d + \ ? \ d *) \ W (\ W +) 'gydF4y2Ba,gydF4y2Ba“$ {convertMe($ 1、$ 2)}”gydF4y2Ba)gydF4y2Ba
ans =“这块石头重约4.536公斤”gydF4y2Ba

就像gydF4y2Ba(? ?@)gydF4y2Ba的运算符gydF4y2Ba$ {}gydF4y2Ba操作符可以访问当前活动工作区中的变量。以下gydF4y2BaregexprepgydF4y2Ba命令使用数组gydF4y2Ba一个gydF4y2Ba在基本工作区中定义:gydF4y2Ba

魔术(3)gydF4y2Ba
A = 8 1 6 3 5 7 4 9 2gydF4y2Ba
regexprep (gydF4y2Ba“矩阵_nam的列是_val”gydF4y2Ba,gydF4y2Ba...gydF4y2Ba{gydF4y2Ba“_nam”gydF4y2Ba,gydF4y2Ba“_val”gydF4y2Ba},gydF4y2Ba...gydF4y2Ba{gydF4y2Ba“一个”gydF4y2Ba,gydF4y2Ba'${sprintf(" %d%d%d ", A)}'gydF4y2Ba})gydF4y2Ba
ans = '矩阵A的列是834 159 672'gydF4y2Ba

另请参阅gydF4y2Ba

|gydF4y2Ba|gydF4y2Ba

相关的话题gydF4y2Ba