使用正则表达式的条件组匹配
conditional group matching using regex
如何匹配以特定字符开头的组。
例如我有以下句子:
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
我需要的输出应该创建一个像所有完全限定名称(中间至少有一个 .
)一样的匹配结果,但如果遇到 <
.[=25= 则停止]
所以,结果应该是:
{ package1.class1, package2.class2, package3.class3, package4.class4, package5.package6.class5 }
我写了 ([\w]+\.)+([\w]+)
来解析它,但它也匹配我不想要的 class6.class7
和 class9.class10
。我知道这太离谱了,对此我深表歉意。
因此,我早些时候问我是否可以忽略从特定字符开始的捕获组。
这是我试过的link:regex101
它匹配的所有内容都是正确的,除了匹配 class6.class7
和 class9.class10
.
的部分
我不确定如何进行。我正在使用 C++14,它支持 ECMAScript 语法以及 POSIX 风格。
EDIT :根据@Corion 的建议,我添加了更多详细信息。
EDIT2 : 添加了 regex101 link
只需使用单词边界 \b
并确保第一个字符不是下划线(但仍然是字母):
(\b(?=[^_])[\w]+)
使用以下 Perl 脚本验证:
perl -wlne "print qq(Matched <$_>) for /(\b(?=[^_])[\w]+)/g"
Matched <just>
Matched <any>
针对评论中问题的扩展,下面的正则表达式也会捕获单词 "middle" 中的点(但仍然不允许在单词的开头使用它们):
(\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>
在问题的第三次扩展之后,我扩展了正则表达式以匹配 class 名称但排除了 extends
关键字,并且仅在有 space (\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>
如何匹配以特定字符开头的组。
例如我有以下句子:
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
我需要的输出应该创建一个像所有完全限定名称(中间至少有一个 .
)一样的匹配结果,但如果遇到 <
.[=25= 则停止]
所以,结果应该是:
{ package1.class1, package2.class2, package3.class3, package4.class4, package5.package6.class5 }
我写了 ([\w]+\.)+([\w]+)
来解析它,但它也匹配我不想要的 class6.class7
和 class9.class10
。我知道这太离谱了,对此我深表歉意。
因此,我早些时候问我是否可以忽略从特定字符开始的捕获组。
这是我试过的link:regex101
它匹配的所有内容都是正确的,除了匹配 class6.class7
和 class9.class10
.
我不确定如何进行。我正在使用 C++14,它支持 ECMAScript 语法以及 POSIX 风格。
EDIT :根据@Corion 的建议,我添加了更多详细信息。 EDIT2 : 添加了 regex101 link
只需使用单词边界 \b
并确保第一个字符不是下划线(但仍然是字母):
(\b(?=[^_])[\w]+)
使用以下 Perl 脚本验证:
perl -wlne "print qq(Matched <$_>) for /(\b(?=[^_])[\w]+)/g"
Matched <just>
Matched <any>
针对评论中问题的扩展,下面的正则表达式也会捕获单词 "middle" 中的点(但仍然不允许在单词的开头使用它们):
(\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>
在问题的第三次扩展之后,我扩展了正则表达式以匹配 class 名称但排除了 extends
关键字,并且仅在有 space (\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>