我需要写一个让我挠头的正则表达式。基本上我有一列数据包括如下的值:
$DATA_DIR
我想要做的是查找术语ACME Corp 123
Corp 742 ACME
Random Text
Broadway 1785 FB
和ACME
。如果存在,那就保持这一点。如果两者都不存在,请保留整个字符串。因此上面的列将转入:
BROADWAY
这有意义吗?
答案 0 :(得分:4)
这个让我挠了一下头。我确定单独使用正则表达式不是解决此问题的最佳方法,但是,这是您的解决方案。
<强>正则表达式强>
^.*?((?(?=.*?(\b(?:broadway|acme)\b).*?)\2|.*)).*?$
<强>换人强>
第1组如下。您可以从匹配数组中收集组1变量,但如果要替换,可以使用以下
$1
注意:我添加了另一个字符串作为测试,以确保如果任何一个单词放在一行中途,它仍会捕获它。
ACME Corp 123
Corp 742 ACME
Some ACME some
Random Text
Broadway 1785 FB
ACME
ACME
ACME
Random Text
Broadway
使用不区分大小写的i
和多行m
标记:
^
在行首处断言位置.*?
任意次数匹配任何字符,但尽可能少((?(?=.*?(\b(?:broadway|acme)\b).*?)\2|.*))
分成几部分
()
捕获以下内容
(?(?=...))
if / else statement (?=.*?(\b(?:broadway|acme)\b).*?)
积极前瞻以匹配以下.*?
任意次数的任何字符,但尽可能少(...)
将以下内容捕获到捕获组2 \b(?:broadway|acme)\b
字边界,后跟broadway
或acme
,后跟字边界.*?
任意次数的任何字符,但尽可能少\2
如果if / else语句为 true (它与上述内容匹配),请捕获该组(如上所述) - 这只是broadway
或{{ 1}} acme
如果if / else语句为 false ,则可以多次匹配任何字符.*
任意次数匹配任何字符,但尽可能少.*?
断言行尾的位置答案 1 :(得分:2)
足以解决此问题的正则表达式是:
^(?(?=(acme|broadway))\1|[\w\s])+?$
为什么这个足够了?如果输入字符串中包含acme
或broadway
,则组1将捕获该值。如果第1组为空,则完全匹配是您的结果。
击穿:
^(? # start conditional
(?= # lookahead for position before
( # group 1 start
acme|broadway # either "acme" or "broadway"
) # group 1 end
)
\1 # if found, then match group 1
| # else
[\w\s] # read a word char or space
)+?$ # do this over and over again, non-greedy
看一下
答案 2 :(得分:0)
这是另一次尝试:
(?:^.*)(ACME)(?:.*$)?|(?:^.*)(Broadway)(?:.*$)|^.*$
正则表达式code in use。
这与Marc Lambrichs的解决方案很接近,但使用了两个捕获组(这可能会更糟 - 但这取决于您的需求)。如果两个组中没有一个($ 1或$ 2)匹配,您将在完全匹配中找到随机文本。
如果您不喜欢第二个捕获组,可以试试这个:
(?:^.*?)(ACME|Broadway)(?:.*$)?|^.*?$
或者如果你想在ctwheels解决方案中拥有1美元的所有东西:
(?(?=(?:^.*?)?(ACME|Broadway)(?:.*$)?)\1|(^.*?$))
正如Marc所指出的,我的方法的另一个优点是它不需要所有正则表达式引擎都没有的高级功能。
但是,第三个正则表达式中使用的conditional Regex并不是随处可用。
答案 3 :(得分:0)
使用先行断言
的另一种解决方案不^.*(ACME|Broadway).*$
说明:
^ # beginning of the string
.* # match any character any number of times
( # start of capture group
ACME|Broadway # if the input string has ACME or Broadway capture in the memory($1)
) # end of the capture group
.* # match any character any number of times
$ # end of the string
https://regex101.com/r/mDCL5g/1
此外,您可以在 JavaScript 中使用相同的正则表达式,如下所示
'ACME Corp 123'.replace(/^.*(ACME|Broadway).*$/, '$1'); // ACME
'Corp 742 ACME'.replace(/^.*(ACME|Broadway).*$/, '$1'); // ACME
'Random Text'.replace(/^.*(ACME|Broadway).*$/, '$1'); // Random Text
'Broadway 1785 FB'.replace(/^.*(ACME|Broadway).*$/, '$1'); // Broadway