正则表达式用于查找包含可选包含和排除单词列表的单词组

时间:2016-08-18 16:15:11

标签: javascript regex string

我尝试构建一个JavaScript友好的正则表达式,匹配任何以某一组单词(A)开头的字符串,如果字符串中包含其他单词,则它们必须位于一组单词(B)或不在一组词(C)中。

因此,给出以下单词组(A),(B)和(C):

(A) Test, Sample
(B) Good, Stuff
(C) Hello, World

并给出以下示例字符串,以(A)中的任何单词开头:

Test
Test Good
Sample Stuff 
Test Hello 
Sample World 
Test Hello Stuff 
Sample Good World
Test Other
Test Other Stuff 
Sample Other World
Test Other Stuff Other

将匹配以下字符串:

Test
Test Good
Sample Stuff
Test Other Stuff 
Test Other Stuff Other

理想情况下,只有A组中的单词("测试"和#34;样本"在这种情况下)将被表达式使用,其余的将由正面和负面的前瞻处理。但是,我也可以使用以(A)开头可能包含(B)但不包含(C)的全部或部分字符串。

我已经在这个问题上工作了好几天了,到目前为止我在这个网站上找到的最接近的答案是:

Is there a regex to match a string that contains A but does not contain B

然而,那里建议的解决方案不包括要求单独匹配起始单词(如我的例子中第一次匹配"测试")。

我最接近解决方案的是以下表达式:

^(Test|Sample).*(?=(Good|Stuff))(?!.*(Hello|World)).*

请参阅此处查看工作示例:

https://regex101.com/r/nL0iE3/1

然而,这与(A)中的单个单词实例(例如" Test")不匹配,并且当它们出现在(B)中的单词之前时匹配(C)中的单词(例如"样本World Good")。

我希望这是有道理的,但如果我能进一步澄清,请告诉我。我会非常感谢任何正确方向的帮助或指示。

3 个答案:

答案 0 :(得分:2)

我希望我理解正确,但我认为你正在寻找

^(Test|Sample)(?!.*(Hello|World))(?=$|.*(Stuff|Other)).*

测试live on regex101.com

<强>解释

^                     # Start of string
(Test|Sample)         # Match Test or Sample
(?!.*(Hello|World))   # Assert that neither Hello nor World are in the string
(?=$|.*(Stuff|Other)) # Assert that the string is over here or that Stuff/Other follows
.*                    # Match rest of string

答案 1 :(得分:1)

Geo's之后的答案,我今天设法轻微地重构了他提供的表达式:

(?=(^(?!.*(Hello|World)).*))(^(Test|Sample)$|^(Test|Sample).*(?=(Good|Stuff)).*$)

要:

(?=(^(?!.*(Hello|World)).*))^(Test|Sample)($|.*(?=(Good|Stuff)).*$)

查看有效版本here

此版本无需在表达式中出现两次字符串起始字(组A字)。否则,表达式的运行方式与Geo在答案中解释的方式相同。

希望这对其他人有帮助。

答案 2 :(得分:0)

(?=(^(?!.*(Hello|World)).*))(^(Test|Sample)$|^(Test|Sample).*(?=(Good|Stuff)).*$)

在此处查看工作:https://regex101.com/r/qX2xS6/2

快速解释:

首先排除所有Hello|World 然后_ 与匹配的字符串(到目前为止) _做其余的匹配。

休息匹配
匹配仅包含一个单词的行:Test|Sample
- 或 -
匹配以Test|Sample开头且包含Good|Stuff

的行