Perl可选组在任意位置

时间:2019-04-11 15:29:40

标签: regex perl optional

我需要捕获Sereral组,其中一些是可选的。我已经在https://www.regular-expressions.info/optional.html中阅读了有关可选的内容,但?对我不起作用。示例文件:

Code>1<Code
foo
Prod>2<Prod
foo
Type>3<Type

perl -0777ne 'print qq($1;$2;$3) if /Code>(.*?)<Code.*?Prod>(.*?)<Prod.*?Type>(.*?)<Type/s' < tst.txt按预期提供1;2;3

现在,我想为第二组添加可选性,例如perl -0777ne 'print qq($1;$2;$3) if /Code>(.*?)<Code.*?(Prod>(.*?)<Prod)?.*?Type>(.*?)<Type/s' < tst.txt,但是它停止打印第二组,并给出1;;(由于嵌套的第3个空白与第2个相同,$ 4打印{{1} }。

Optional Group Expression我都尝试过3,但又尝试过perl -0777ne 'print qq($1;$2;$3;$4) if /Code>(.*?)<Code.*?(Prod>(.*?)<Prod|.*?).*?Type>(.*?)<Type/s' < tst.txt

是否可以在任意位置进行提取,因为我可以在组之间添加其他内容?

编辑: 删除一个1;;;3 ?会给出
perl -0777ne 'print qq($1;$2;$3;$4) if /Code>(.*?)<Code.*?(Prod>(.*?)<Prod|.*).*?Type>(.*?)<Type/s' < tst.txt 因此将捕获第一和第三之间的所有内容(看起来像提取了第二个选项,而不是1; foo Prod>2<Prod foo ;;3之前的一个),而不仅仅是第二个。

编辑: 实施了|条建议,现在?:给出了perl -0777ne 'print qq($1;$2;$3;$4) if /Code>(.*?)<Code.*?(?:Prod>(.*?)<Prod|.*).*?Type>(.*?)<Type/s' < tst.txt

1 个答案:

答案 0 :(得分:3)

您正在寻找(?:...)-捕获组中的?:前缀将其简单地分为一个组,而不是捕获的组。我建议每次都没有捕获一个组时使用它,以使您的意图更清晰。它说:“我将其分组,但不保留。”它甚至可以使运行时更快,但这不是主要优点。

示例:

perl -0777nE 'say qq[$1;$2;$3] if /Code\>(.*?)\<Code.*?(?:Prod\>(.*?)\<Prod.*?)?Type\>(.*?)\<Type/s' < t

这会打印出1;2;3

但是,我还建议您查看(?<name>...)语法,在其中您可以命名组并使用%+(例如$+{name})按名称而不是位置提取字段。以我的经验,这使得正则表达式和依赖它的代码都更具可读性。