主要内容GydF4y2Ba

动态正则表达式GydF4y2Ba

介绍GydF4y2Ba

在动态表达式中,您可以制作您想要的模式GydF4y2Baregexp.GydF4y2Ba匹配依赖于输入文本的内容。通过这种方式,您可以更紧密地匹配被解析的文本中的不同输入模式。您还可以使用更换条款使用的动态表达式GydF4y2Baregexprep.GydF4y2Ba函数。这使您能够根据已解析的输入调整替换文本。GydF4y2Ba

属性中可以包含任意数量的动态表达式GydF4y2Bamatch_exprGydF4y2Ba或GydF4y2Bareplace_exprGydF4y2Ba这些命令的论据:GydF4y2Ba

Regexp (text, match_expr) Regexp (text, match_expr) regexprep(text, match_expr, replace_expr)GydF4y2Ba

作为动态表达式的示例,以下GydF4y2Baregexprep.GydF4y2Ba命令正确替换该术语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 =“国际化”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 =“国际化”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

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

此特定命令的目的是找到一系列GydF4y2BaXGydF4y2Ba存储在输入单元格数组中的每个字符向量中的字符。但是要注意的是GydF4y2BaXGydF4y2BaS在每个字符向量中都不同。如果计数没有变化,则可以使用该表达式GydF4y2Bax {n}GydF4y2Ba表示您想要匹配GydF4y2BaN.GydF4y2Ba这些字符。但是,一个常数GydF4y2BaN.GydF4y2Ba在这种情况下不起作用。GydF4y2Ba

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

正则表达式(空空的,GydF4y2Ba' ^ (\ d +) (? ? X美元{1})的美元GydF4y2Ba那GydF4y2Ba“匹配”GydF4y2Ba那GydF4y2Ba'一次'GydF4y2Ba的)GydF4y2Ba
ans = 1×3单元阵列{'5xxxxx'} {'8xxxxxxxxx} {'1x'}GydF4y2Ba

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

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

例如,使用动态表达式GydF4y2Ba(? ? @flilplr(1美元))GydF4y2Ba以定位嵌入到更大字符向量中的回文“绝不是奇数或偶数”。GydF4y2Ba

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

装备=低(GydF4y2Ba...GydF4y2Ba'找到palindrome从不奇怪,甚至在这个字符串中'GydF4y2Ba);装备= regexprep(空空的,GydF4y2Ba'\ w *'GydF4y2Ba那GydF4y2Ba''GydF4y2Ba的)GydF4y2Ba
装备= ' findthepalindromeneveroddoreveninthisstring 'GydF4y2Ba

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

palindrome = regexp(chr,GydF4y2Ba”({3})? (? ? @fliplr(1美元))”GydF4y2Ba那GydF4y2Ba“匹配”GydF4y2Ba的)GydF4y2Ba
Palindrome = 1×1 cell array {'neveroddoreven'}GydF4y2Ba

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

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

有趣= @fliplr;palindrome = regexp(chr,GydF4y2Ba”({3})? (? ? @fun(1美元))”GydF4y2Ba那GydF4y2Ba“匹配”GydF4y2Ba的)GydF4y2Ba
Palindrome = 1×1 cell array {'neveroddoreven'}GydF4y2Ba

服务于功能目的的命令- (?@cmd)GydF4y2Ba

这GydF4y2Ba(?@cmd)GydF4y2Ba操作员指定MATLAB命令GydF4y2Baregexp.GydF4y2Ba或GydF4y2Baregexprep.GydF4y2Ba在解析整个匹配表达式时运行。与MATLAB中的其他动态表达式不同,此操​​作员不会更改它在中使用的表达式的内容。相反,您可以使用此功能来获取MATLAB以报告它所采取的步骤,因为它会解析其中一个的内容常用表达。此功能可用于诊断正则表达式。GydF4y2Ba

下面的示例解析一个单词,它包含0个或多个字符,后面跟着两个相同的字符,后面又包含0个或多个字符:GydF4y2Ba

regexp(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然后GydF4y2BaP.GydF4y2Ba和下一个GydF4y2BaP.GydF4y2Ba,此时停止,因为匹配最终得到满足:GydF4y2Ba

regexp(GydF4y2Ba密西西比州的GydF4y2Ba那GydF4y2Ba' \ w * (\ w) (? @disp(1美元))\ 1 \ w *’GydF4y2Ba那GydF4y2Ba“匹配”GydF4y2Ba的)GydF4y2Ba
i p p ans = 1×1个单元阵列{'mississippi'}GydF4y2Ba

现在再试一次相同的例子,这次让第一个量词lazy (GydF4y2Ba*?GydF4y2Ba)。同样,Matlab会使同样的比赛:GydF4y2Ba

regexp(GydF4y2Ba密西西比州的GydF4y2Ba那GydF4y2Ba‘\ w * ? (\ w) \ 1 \ w *’GydF4y2Ba那GydF4y2Ba“匹配”GydF4y2Ba的)GydF4y2Ba
ans = 1×1个单元阵列{'mississippi'}GydF4y2Ba

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

regexp(GydF4y2Ba密西西比州的GydF4y2Ba那GydF4y2Ba‘\ w * ? (\ w) (? @disp(1美元))\ 1 \ w *’GydF4y2Ba那GydF4y2Ba“匹配”GydF4y2Ba的)GydF4y2Ba
M i s ans = 1×1个单元阵列{'mississippi'}GydF4y2Ba

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

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

matches = {};expr = [GydF4y2Ba(欧拉\年代)?(柯西\ s) ?(布尔)? (? @ if (~ isempty($ &)),“GydF4y2Ba...GydF4y2Ba'匹配{end + 1} = $&;结束)(?!)'GydF4y2Ba];regexp(GydF4y2Ba“欧拉柯西布尔”GydF4y2Ba, expr);匹配GydF4y2Ba
匹配= 1×6个单元格阵列{'euler cauchy bo ...'} {'euler cauchy'} {'euler'} {'cauchy boole'} {'cauchy'} {'cauchy'} {'boole'}GydF4y2Ba

运营商GydF4y2Ba$&GydF4y2Ba(或等效GydF4y2Ba$ 0.GydF4y2Ba),GydF4y2Ba$`GydF4y2Ba,GydF4y2Ba$'GydF4y2Ba请参阅当前是匹配的输入文本的那部分,在当前匹配之前的所有字符以及所有字符分别遵循当前匹配。使用动态表达式时,这些运营商有时有用,特别是那些雇用的GydF4y2Ba(?@cmd)GydF4y2Ba操作符。GydF4y2Ba

此示例解析了查找字母的输入文本GydF4y2BaGGydF4y2Ba.在文本的每一次迭代中,GydF4y2Baregexp.GydF4y2Ba比较当前角色GydF4y2BaGGydF4y2Ba,找不到它,就去找下一个角色。该示例通过标记正在解析的当前位置来跟踪扫描文本的进度GydF4y2Ba^GydF4y2Ba特点。GydF4y2Ba

(GydF4y2Ba$`GydF4y2Ba和GydF4y2Ba$'GydF4y2Ba操作符捕获当前解析位置前后的文本部分。您需要两个单引号(GydF4y2Ba$''GydF4y2Ba)表达序列GydF4y2Ba$'GydF4y2Ba当它出现在文本中时。)GydF4y2Ba

Chr =.GydF4y2Ba“abcdefghij”GydF4y2Ba;expr =GydF4y2Ba‘(?@disp (sprintf(“开始比赛:[% s ^ % s ]'',$`,$''))) g’GydF4y2Ba;Regexp(Chr,Expr,GydF4y2Ba'一次'GydF4y2Ba);GydF4y2Ba
start match: [abcdefghij] Starting match: [abcdefghij] Starting match: [abcdefghij] Starting match: [abcdefghij] Starting match: [abcdefghij] Starting match: [abcdefghij] Starting match: [abcdefghij] Starting match: [abcdefghij] Starting match: [abcdefghij]GydF4y2Ba

替代表达式的命令 - $ {cmd}GydF4y2Ba

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

在GydF4y2Baregexprep.GydF4y2Ba呼叫在此显示,替换模式是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, units)GydF4y2Ba开关GydF4y2Ba(单位)GydF4y2Ba情况下GydF4y2Ba“英寸”GydF4y2BaFun = @(in)in .* 2.54;Uout =GydF4y2Ba“厘米”GydF4y2Ba;GydF4y2Ba情况下GydF4y2Ba'里程'GydF4y2BaFun = @(mi)mi。* 1.6093;Uout =GydF4y2Ba'公里GydF4y2Ba;GydF4y2Ba情况下GydF4y2Ba“英镑”GydF4y2BaFun = @(lb)lb。* 0.4536;Uout =GydF4y2Ba“公斤”GydF4y2Ba;GydF4y2Ba情况下GydF4y2Ba“品脱”GydF4y2BaFun = @(pt)pt .* 0.4731;Uout =GydF4y2Ba“升”GydF4y2Ba;GydF4y2Ba情况下GydF4y2Ba“盎司”GydF4y2Ba有趣= @(oz)oz。* 28.35;Uout =GydF4y2Ba'克'GydF4y2Ba;GydF4y2Ba结尾GydF4y2Baval =乐趣(str2num(valin));Valout = [num2str(val)GydF4y2Ba' 'GydF4y2Bauout];GydF4y2Ba结尾GydF4y2Ba

在命令行中,调用GydF4y2BaconvertMeGydF4y2Ba功能从GydF4y2Baregexprep.GydF4y2Ba,传递值的数量要转换和帝国单位的名称: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
这个水罐能装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操作符可以访问当前活动工作区中的变量。以下GydF4y2Baregexprep.GydF4y2Ba命令使用数组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”)}”GydF4y2Ba})GydF4y2Ba
ans = '矩阵A的列是834 159 672'GydF4y2Ba

也可以看看GydF4y2Ba

|GydF4y2Ba|GydF4y2Ba

相关的话题GydF4y2Ba