我有这样的文字:
TEXT 786
OPQ RTS
APPENDIX A
TITLE
TEXT 123
ABC EFG
APPENDIX B
TEXT 456
HIJ KLM
和
TEXT 786
OPQ RTS
APPENDIX A
TITLE
TEXT 123
ABC EFG
TEXT 456
HIJ KLM
我尝试使用正则表达式提取从APPENDIX A
到APPENDIX B
的所有文本,如果APPENDIX B
存在,否则从APPENDIX A
到结束(即,HIJ KLM
)。此外,APPENDIX A
必须出现在TITLE
之前的15个字之内。这就是我到目前为止所提出的:
(\b(?:appendix)(?:.){0,15}(?:title)(?:.*)(?:appendix){0,1})/is
问题是,如果APPENDIX B
存在,捕获不会停留在APPENDIX B
,它会一直捕获到最后。
答案 0 :(得分:1)
一种方法是对可选部分使用交替
perl -0777 -wlnE'
@m = /(appendix .{0,15} title (?: .*?appendix\s\w+ | .*) )/xsig;
say for @m
' input.txt
/g
,以匹配appendix
个标记中的所有部分。
或者使用多个组进行捕获,一个用于可选项目,然后对其进行测试并相应地使用
perl -0777 -wne'
@m = /(appendix .{0,15} title) (.*? appendix\s\w+)? (.*)/xsi;
print join "", ($m[1] ? @m[0,1] : @m[0,2])
' input.txt
这是有效的,因为$2
是为第二个(
创建的,即使没有匹配也是如此。
使用更多捕获组,您可以在第二种情况下过滤? grep { defined } @m
。如果可能有多个appendix
- 部分在此方法中更好地使用while
和$N
个变量
while (/(appendix.{0,15}title)(.*?appendix\s\w+)?(.*)/sig) {
my $appx_section = ($2) ? $1.$2 : $1.$3;
...
}
因为所有捕获的一个大@m
需要一点点分析。
所有这些都会在两种情况下打印所需的输出,包括多个appendix
- 部分。
我已将其包装在单行中进行准备测试。代码在Perl脚本中工作。
答案 1 :(得分:0)
答案 2 :(得分:0)
就像这样,$ var是你的字符串。
if ( $var=~m#(APPENDIX A.{0,15}TITLE.*?(?:APPENDIX B|$))#s )
{
print $1."\n";
}
else
{
print "failed\n";
}
你的问题是这个"(?:。)(?:附录){0,1})"贪婪的匹配加上{0,1},这意味着它总是会占用很多,因为正则表达式是贪婪的。 ?是非贪婪的,例如,只需尽可能少地进行比赛