使用正则表达式进行条件组匹配

时间:2019-02-01 08:50:43

标签: c++ regex perl pcre ecmascript-5

如何匹配组,除非该组以特定字符开头。

例如我有以下一句话:

just _checking any _string.

我有与所有单词([\w]+)匹配的正则表达式{just, _checking, any, _sring}。但是,我想要匹配所有不以字符_开头的单词,即{just, any}

上面的示例是我实际上试图解析的内容的简化版本。

我正在解析一个代码文件,其中包含以下格式的字符串:

package1.class1<package2.class2 <? extends package3.class3> , package4.class4 <package5.package6.class5<?>.class6.class7<class8> >.class9.class10

我需要的输出应该创建一个匹配结果,就像所有全限定名称(中间至少有一个.)一样,但是如果遇到<则停止。

因此,结果应为:

{ package1.class1, package2.class2, package3.class3, package4.class4, package5.package6.class5 }

我写了([\w]+\.)+([\w]+)来解析它,但它也匹配了我不想要的class6.class7class9.class10。我知道这还差得远,对此我深表歉意。

因此,我早些时候问过我是否可以忽略从特定字符开始的捕获组。

这是我尝试过的链接:regex101

除了class6.class7class9.class10匹配的部分以外,所有匹配的东西都是正确的。

我不确定该如何进行。我使用的是C ++ 14,它也支持ECMAScript语法以及POSIX样式。

编辑:如@Corion所建议,我添加了更多详细信息。 EDIT2 :添加了regex101链接

1 个答案:

答案 0 :(得分:2)

只需使用单词边界\b,并确保第一个字符不是下划线(但仍然是字母):

(\b(?=[^_])[\w]+)

使用以下Perl脚本进行验证:

perl -wlne "print qq(Matched <$_>) for /(\b(?=[^_])[\w]+)/g"

Matched <just>
Matched <any>

regex101 playground

为回应注释中问题的扩展,以下正则表达式还将捕获单词“中间”的点(但仍不允许在单词开头添加点):

(\b(?=[^_.])[\w.]+)

perl -wlne "print qq(Matched <$_>) for /(\b(?=[^_.])[\w.]+)/g"

just _checking any _string. and. this. inclu.ding dots
Matched <just>
Matched <any>
Matched <and.>
Matched <this.>
Matched <inclu.ding>
Matched <dots>

regex101 playground

在问题的第三次扩展之后,我扩展了正则表达式以匹配类名,但排除了extends关键字,并且仅在有空格(\s )或小于号(<)。通过强制点号(\.出现在比赛中来实现完全合格的比赛:

(?:^|[<>\s])(?:(?![_.]|\bextends\b)([\w]+\.[\w.]+))

perl -nwle "print qq(Matched <$_>) for /(?:^|[<>\s])(?:(?![_.]|\bextends\b)([\w]+\.[\w.]+))/g"

Matched <package1.class1>
Matched <package2.class2>
Matched <package3.class3>
Matched <package4.class4>
Matched <package5.package6.class5>

regex 101 playground