有时大括号匹配,在少数情况下不会。
我的代码:
use strict;
use warnings;
my $str1 = '$$\eqalign{&\cases{\mathdot{\bf x}=A{\bf x}+Bu\cr y=H{\bf x}}\quad{\rm with}\{\bf x}=\left(\matrix{x\cr\mathdot{x}\cr\theta\cr\mathdot{\theta}}\right),\cr&A\!=\!\!\left(\matrix{0&1&0&0\cr 0&0&-{m_{a}\over M}g&0\cr 0&0&0&1\cr 0&0&{(M\!+\!m_{a})\over Ml}g&0}\right)\!,\ B\!=\!\left(\matrix{0\cr{a\over M}\cr 0\cr-{a\over Ml}}\right)\!,\ H^{T}\!=\!\left(\matrix{1\cr 0\cr 1\cr 0}\right)\!.}$$';
my $str2 = "\\bibcite{Airdetal2013}{{2}{2017}{{{John} {et~al.}}}{{{James}, {Flexi}, {Buella}, {Curren}, {Mozes}, {Sam}, {Kandan}, {Alexander}, {Alfonsa}, {Fireknight}, {Georgen}, {Karims}, {Merloni}, {Nanda}, {Terra}, {Alvato}, {Nini}, {Winski}, {Shankar}, {Gnali}, \& {Giito}}}}";
my $regex = qr/(?:[^{}]*(?:{(?:[^{}]*(?:{(?:[^{}]*(?:{[^{}]*})*[^{}]*)})*[^{}]*)*})*[^{}]*)*/;
if($str1=~m/\{$regex\}/) { print "str1: $&\n"; }
if($str2=~m/\{$regex\}/) { print "str2: $&\n"; }
OUTPUT:
str1: {&\cases{\mathdot{\bf x}=A{\bf x}+Bu\cr y=H{\bf x}}\quad{\rm with}\ {\bf x}=\left(\matrix{x\cr\mathdot{x}\cr\theta\cr\mathdot{\theta}}\right),\cr&A\!=\!\!\left(\matrix{0&1&0&0\cr 0&0&-{m_{a}\over M}g&0\cr 0&0&0&1\cr 0&0&{(M\!+ !m_{a})\over Ml}g&0}\right)\!,\ B\!=\!\left(\matrix{0\cr{a\over M}\cr 0\cr-{a\over Ml}}\right)\!,\ H^{T}\!=\!\left(\matrix{1\cr 0\cr 1\cr 0}\right)\!.}
str2: {2}
str1 is correct output. str2 incorrect output.
Expected Output on str2 is:
str2: {{2}{2017}{{{John} {et~al.}}}{{{James}, {Flexi}, {Buella}, {Curren}, {Mozes}, {Sam}, {Kandan}, {Alexander}, {Alfonsa}, {Fireknight}, {Georgen}, {Karims}, {Merloni}, {Nanda}, {Terra}, {Alvato}, {Nini}, {Winski}, {Shankar}, {Gnali}, \& {Giito}}}}
在示例中,str1字符串与嵌套的花括号不匹配。但是第二个样本str12字符串可以匹配嵌套的花括号。
这是我的问题可以匹配嵌套的花括号。我很无能为力。如果有人指出我的错误会更好。
提前致谢。
答案 0 :(得分:2)
注意问题中的修改会在前面添加\\bibcite{Airdetal2013}
。但是,这不会改变下面的分析,因为它不会改变整体嵌套级别。
必须以更好的方式做到这一点。 Wiktor Stribiżew在评论中提供了递归正则表达式。有用于递归解析的模块。还有解析Latex的工具。
然而,出于好奇......
你的字符串,适当缩短
my $str2 = "{{2}{2017}{{{John}{et~al.}}}{{{James}, ... {Gnali}, \& {Giito}}}}";
或者,C
代表一对有内部物品的曲线(没有嵌套)
"{ C C { { C C } { C, ... \& C } } }"
所以你有三个级别的嵌套,以达到最后一对{...}
(没有进一步的嵌套)。
你的正则表达式,与$nc = qr/[^{}]*/
(非卷曲)展开,以便我们可以查看它
my $regex = qr/
(?: $nc
(?: {
(?: $nc
(?: {
(?: $nc (?: { $nc } )* $nc )
}
)* $nc
)*
}
)* $nc
)*/x;
我可以在这里算两个级别。 ($nc
没有curlies,因此{ $nc }
与我上面的C
匹配。)
因此这个正则表达式不能匹配整个字符串。
如何解决?最好,找到另一种方式,以免淹没在这。
或者,像上面那样写出来,非常小心,并添加缺失的等级。
答案 1 :(得分:2)
由于您的实际要求(discussed in the chat)要匹配以Application.DisplayAlerts = True
开头的子字符串,后跟\bib
子字符串或除{...}
和{
以外的任何字符,你应该使用带有子程序的正则表达式:
}
<强>详情:
/\\bib(?:({(?:[^{}]++|(?1))*})|(?!\\bib)[^{}])*/g
- \\bib
文字文字\bib
- 出现以下情况:
(?:({(?:[^{}]++|(?1))*})|(?!\\bib)[^{}])*
- 第1组(将使用({(?:[^{}]++|(?1))*})
递归)匹配
(?1)
- 文字{
{
- 除(?:[^{}]++|(?1))*
和{
或整个第1组子模式之外的0个或多个1个字符出现}
- 文字}
}
- 或|
- (?!\\bib)[^{}]
和{
之外的字符不会启动}
字面字符序列。请参阅sample Perl code:
\bib