正则表达式:是否有 AND 运算符?

Regular Expressions: Is there an AND operator?

提问人:hugoware 提问时间:1/23/2009 最后编辑:vijroxhugoware 更新时间:3/3/2023 访问量:1212292

问:

显然,您可以使用(管道?)来表示,但是有没有一种方法也可以表示呢?|ORAND

具体来说,我想匹配包含某个短语的所有段落,但没有特定的顺序。

表达式正则表达式环视

评论

2赞 Nietzche-jou 1/23/2009
您的意思是您想在文本中查找短语,其中每个这样的短语都是给定短语中单词的有效排列?
3赞 Zachary Vance 8/21/2010
我把它放在这里是因为有三四个答案忽略了它。Lookahead 不会匹配每个子句的相同长度,除非它们以 $ 结尾。一个前瞻可以匹配 4 个字符,另一个 6 个字符。例如,(?=a*)(?=aab) 将匹配 aabaaaaba
4赞 11/14/2011
尝试仅使用“空格”字符作为“AND”运算符。
0赞 1/8/2019
1. .2. 包含乱序文本。第 1 条是可以解释的。第 2 点可以通过几种方式完成。方式 1:,方式 2:在这种情况下,在这种情况下,在段落的定义正式确定之前,段落的匹配是未定义的。I'd like to match paragraphs of text(?:(?:(?(1)(?!))\b(phrase1)\b.*?|(?(2)(?!))\b(phrase2)\b.*?)){2}(?=.*\bphrase1\b)(?=.*\bphrase2\b)
0赞 Karl Knechtel 8/12/2022
“具体来说,我想匹配包含某个短语的所有文本段落,但没有特定的顺序。”这与实际情况不同,这使问题变得混乱。 检查当前位置是否匹配两种模式中的任何一种。它不会检查字符串的其余部分是否至少包含这两个内容之一。然后,“and”对应项将检查两种模式在当前位置是否匹配;但是您显然想搜索字符串并检查所有模式是否匹配其中的某个地方。||

答:

11赞 pilif 1/23/2009 #1

顺序始终隐含在正则表达式的结构中。为了实现你想要的,你必须将输入字符串与不同的表达式进行多次匹配。

您想要执行的操作无法使用单个正则表达式。

评论

0赞 Robert P 1/23/2009
这在技术上并非不可能,但不值得实施。我不知道为什么有人投了反对票......
13赞 Alan Moore 1/23/2009
可能是因为它不仅可能,而且很简单,假设你的正则表达式风格支持前瞻。这是一个很好的选择;当今大多数主要的编程语言都支持它们。
15赞 user54579 1/23/2009 #2

在您的情况下,是否不可能对多个匹配结果执行 AND?在伪代码中

regexp_match(pattern1, data) && regexp_match(pattern2, data) && ...

评论

3赞 Alan Wolfe 9/5/2015
我的情况是,我有一些代码是规则的数据表,其中包含单个正则表达式模式匹配字符串来测试规则的有效性。在我的情况下,我无法进行多项测试,在其他人的情况下也是如此!
0赞 赣西狠人 5/7/2022
@AlanWolfe我现在正在处理完全相同的案件......那么你有没有想出处理逻辑 AND 的正确方法?
505赞 Jason Cohen 1/23/2009 #3

使用非消耗性正则表达式。

典型的(即Perl/Java)表示法是:

(?=经验)

这意味着“匹配 expr,但之后继续在原始匹配点匹配”。

你可以随心所欲地做这些事,这将是一个“和”。例:

(?=match this expression)(?=match this too)(?=oh, and this)

如果需要在非消费表达式中保存某些数据,您甚至可以在其中添加捕获组。

评论

4赞 Robert P 1/23/2009
perl -e “q{一些东西和东西} =~ /(?=一些)(?=东西)(?=东西)/ ?print 'yes' : print 'no'“ 打印 'no'。
34赞 strager 1/23/2009
应该提到的是,这个特定的例子被称为积极前瞻性断言。除了“和”之外,它还有其他用法。请注意,文本不会被使用。
8赞 Nietzche-jou 1/23/2009
像这样使用 (?=) 会导致正则表达式永远不会成功。但它 |的连词类比。OP在他认为可以解决他的问题方面是错误的。
12赞 kriss 6/15/2010
perl -e “q{一些东西和东西} =~ /(?=.*some)(?=.*stuff)(?=.*things)/ ?print 'yes' : print 'no'”
3赞 Pithikos 11/25/2011
你能在你的答案中添加一些perl代码中的简单例子吗?
10赞 jpalecek 1/23/2009 #4

如果使用 Perl 正则表达式,则可以使用正 lookahead:

例如

(?=[1-9][0-9]{2})[0-9]*[05]\b

将是大于 100 且可被 5 整除的数字

30赞 Juha Syrjälä 1/23/2009 #5

你可以用正则表达式来做到这一点,但你可能想要其他一些。例如,使用多个正则表达式并将它们组合在一个 if 子句中。

您可以使用标准正则表达式枚举所有可能的排列,如下所示(按任意顺序匹配 a、b 和 c):

(abc)|(bca)|(acb)|(bac)|(cab)|(cba)

但是,如果您有多个术语,则会产生一个非常长且可能效率低下的正则表达式。

如果你使用的是一些扩展的正则表达式版本,比如Perl的或Java的,他们有更好的方法来做到这一点。其他答案建议使用积极的前瞻操作。

评论

10赞 Casimir et Hippolyte 6/14/2013
我不认为你的方法比 3 次灾难性的回溯更低效。当然,编写时间较长,但请注意,您可以轻松地自动生成模式。请注意,您可以使用 改进它以更快地失败。最重要的是,您可以将其与所有正则表达式风格一起使用。a(bc|cb)|b(ac|ca)|c(ab|ba)
475赞 Alan Moore 1/23/2009 #6

正如其他一些响应者所说,您需要使用 lookahead,但 lookahead 必须考虑其目标单词和当前匹配位置之间的其他字符。例如:

(?=.*word1)(?=.*word2)(?=.*word3)

在第一次展望中,它允许它在到达“word1”之前匹配所需的任何字符数。然后重置匹配位置,第二个展望寻找“word2”。再次重置,最后一部分匹配“word3”;由于这是您要检查的最后一个单词,因此没有必要将其放在展望中,但它不会造成伤害。.*

为了匹配整个段落,您需要在两端锚定正则表达式并添加一个 final 以消耗剩余的字符。使用 Perl 风格的表示法,这将是:.*

/^(?=.*word1)(?=.*word2)(?=.*word3).*$/m

“m”修饰符用于多行模式;它允许 AND 在段落边界处匹配(正则表达式中的“行边界”)。在这种情况下,您不能使用“s”修饰符,它允许点元字符与换行符以及所有其他字符匹配。^$

最后,你要确保你匹配的是整个单词,而不仅仅是较长单词的片段,所以你需要添加单词边界:

/^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$/m

评论

9赞 Lincoln 9/19/2012
完全正确 - 还有一个关于这个的教程!ocpsoft.org/tutorials/regular-expressions/and-in-regex
4赞 zx81 5/17/2014
+1 表示清晰简洁的答案,展示了前瞻的最佳用途之一(与黑客等用途不同,用于计算密码匹配的百分比)。:)
0赞 Liam 10/15/2015
MySQL的regexp()是否支持此功能?
1赞 Alan Moore 10/16/2015
@Liam:。MySQL使用POSIX ERE风格,所以没有。它有效地牺牲了功能以支持性能,这在我看来是合理的。这里有更多信息。
4赞 Wesley Smith 7/20/2017
在 JavaScript 中,如果您有新行,请替换为 JavaScript,因为在 JavaScript 的正则表达式引擎中不匹配新行,并且不能使用修饰符进行.*[\s\S]*.
1赞 IGRACH 10/19/2022
请注意,如果您在大数据量上使用大量查找,这可能会给 CPU 带来所有压力。
55赞 fanjabi 4/20/2011 #7

请看这个例子:

我们有 2 个正则表达式 A 和 B,我们希望匹配它们,因此在伪代码中它看起来像这样:

pattern = "/A AND B/"

它可以在不使用 AND 运算符的情况下编写,如下所示:

pattern = "/NOT (NOT A OR NOT B)/"

在PCRE中:

"/(^(^A|^B))/"

regexp_match(pattern,data)

评论

30赞 Alan Moore 11/14/2011
就形式逻辑而言,这是正确的,但在这里绝对没有帮助。在正则表达式中,NOT 可能比 AND 更难表达。
0赞 Melebius 11/18/2013
@marvin_dpr它在 CMake 中对我有用,而另一个建议则不然。它似乎取决于实现。(?=expr)
44赞 Lambda Fairy 12/30/2013
在正则表达式语法中不是“字符串的开头”吗?^
4赞 tripleee 2/17/2015
在正则表达式中,仅在字符类的开头否定。除非 CMake 正在做一些非常时髦的事情(以至于将他们的模式匹配语言称为“正则表达式”可能会被视为误导或不正确),否则我猜它对你有用的事实是一个孤立的事故。^
6赞 Sasha 1/31/2022
这个绝对错误的答案怎么会得到这么多的赞成?!在PCRE中,意味着“行的开始”而不是否定。也许人们可以通过消极的展望(例如)获得一些运气,但肯定不能。/(^(^A|^B))/^(?!…)(?!(?!A)|(?!B))^
5赞 TheTechGuy 9/10/2011 #8

在正则表达式之外使用 AND。在 PHP lookahead 运算符中似乎对我不起作用,而是我使用了这个

if( preg_match("/^.{3,}$/",$pass1) && !preg_match("/\s{1}/",$pass1))
    return true;
else
    return false;

如果密码长度为 3 个字符或更多,并且密码中没有空格,则上述正则表达式将匹配。

13赞 mug896 12/27/2013 #9

为什么不使用 awk?
使用 awk 正则表达式 AND,OR 问题就是这么简单

awk '/WORD1/ && /WORD2/ && /WORD3/' myfile
44赞 yodabar 6/30/2014 #10

AND 运算符隐含在 RegExp 语法中。
OR 运算符必须使用管道指定。
以下正则表达式:

var re = /ab/;

表示字母 AND 字母 。
它还适用于组:
ab

var re = /(co)(de)/;

它意味着组 AND 组 .
将(隐式)AND 替换为 OR 需要以下行:
code

var re = /a|b/;
var re = /(co)|(de)/;

评论

41赞 JESii 9/13/2014
不幸的是,这不是OP所要求的。这以该顺序查找任何内容,而他们希望以任何顺序查找它们。在下面 stackoverflow.com/users/20938/alan-moore 查看答案,哪个是正确的答案。
2赞 yodabar 9/6/2018
@JESii谢谢你的观点,你是对的,我误解了雨果威尔的问题,我特别关注他的第一句话。正如 AlanMoore 所写,正确的答案是正确使用前瞻运算符。无论如何,我认为有人可能会发现我的澄清很有用,因为已经被点赞了,所以我不会把所有东西都扔掉。问候。
0赞 Karl Knechtel 8/12/2022
“表示字母 a 和字母 b”不,它没有;它的意思是紧随其后的是 .,则在同一位置检查两种模式。类似的版本是使用前瞻来测试两种模式是否匹配;但目前尚不清楚比赛应该包括什么ab|
8赞 garbagecollector 11/21/2014 #11

您可以将输出通过管道传递到另一个正则表达式。使用 grep,您可以这样做:

grep A | grep B

9赞 DevWL 11/13/2015 #12

除了公认的答案

我将为你们提供一些实际的例子,让你们中的一些人更清楚地了解事情。例如,假设我们有这三行文本:

[12/Oct/2015:00:37:29 +0200] // only this + will get selected
[12/Oct/2015:00:37:x9 +0200]
[12/Oct/2015:00:37:29 +020x]

在这里看演示 DEMO

我们在这里要做的是选择 + 号,但前提是它在两个带空格的数字之后并且它位于四个数字之前。这些是唯一的限制。我们将使用这个正则表达式来实现它:

'~(?<=\d{2} )\+(?=\d{4})~g'

请注意,如果将表达式分开,则会给出不同的结果。

或者,也许您想在标签之间选择一些文本......但不是标签!然后,您可以使用:

'~(?<=<p>).*?(?=<\/p>)~g'

对于这段文字:

<p>Hello !</p> <p>I wont select tags! Only text with in</p> 

在这里看演示 DEMO

评论

0赞 James Brown 12/6/2018
哪个答案是被接受的答案?请为将来的我添加一个链接。
7赞 hrs 11/25/2020 #13

((yes).*(no))|((no).*(yes))

将匹配同时具有两者的句子,无论它们出现的顺序如何:yesno

Do i like cookies? **Yes**, i do. But milk - **no**, definitely no.

**No**, you may not have my phone. **Yes**, you may go f yourself.

将两者匹配,忽略大小写。

评论

0赞 zabala 5/25/2022
非常高效。
4赞 lochiwei 5/6/2021 #14

以下是“and”运算符的可能“形式”:

以以下正则表达式为例:

如果我们想匹配没有“e”字符的单词,我们可以这样做:

/\b[^\We]+\b/g
  • \W表示不是“单词”字符。
  • ^\W表示“单词”字符。
  • [^\We]表示“单词”字符,但不是“e”。

查看实际操作:不带 E 的 Word

正则表达式的“and”运算符

我认为这种模式可以用作正则表达式的“and”运算符。

一般而言,如果:

  • A = not a
  • B = not b

然后:

[^AB] = not(A or B) 
      = not(A) and not(B) 
      = a and b

差集

因此,如果我们想在正则表达式中实现差分集的概念,我们可以这样做:

a - b = a and not(b)
      = a and B
      = [^Ab]
-1赞 SomeOne 3/3/2023 #15

常见情况:

在javascript中,你可以这样做:

如果要检查密码是否同时包含小字母和大字母,请使用以下命令:

passwordValue.search(/[a-z]/) !== -1 && passwordValue.search(/[A-Z]/) !== -1

如果密码输入同时包含小字母和大字母,则此语句返回 true,否则返回 false。