正则表达式:有and运算符吗?

slsn1g29  于 2021-09-13  发布在  Java
关注(0)|答案(14)|浏览(397)

显然,您可以使用 | (管道?)表示 OR ,但有没有一种方法可以代表 AND
具体来说,我想匹配包含所有特定短语的文本段落,但没有特定顺序。

du7egjpx

du7egjpx1#

使用非消耗性正则表达式。
典型的(即perl/java)表示法是: (?= expr ) 这意味着“匹配表达式,但在此之后,在原始匹配点继续匹配。”
您可以根据需要执行任意多个操作,这将是一个“和”示例: (?=match this expression)(?=match this too)(?=oh, and this) 如果需要在非消费表达式中保存一些数据,甚至可以在其中添加捕获组。

1mrurvl1

1mrurvl12#

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

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

这个 .* 在第一种情况下,lookahead允许它在到达“word1”之前匹配所需的字符数。然后重置匹配位置,第二个前瞻查找“word2”。再次重置,最后一部分匹配“word3”;因为这是你要检查的最后一个词,所以没有必要把它放在前面看,但它不会伤害你。
为了匹配整个段落,您需要在两端锚定正则表达式并添加一个final .* 使用剩余的字符。使用perl风格的表示法,即:

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

“m”修饰符用于多行模式;它让 ^$ 匹配段落边界(正则表达式中的“行边界”)。在这种情况下,不使用“s”修饰符是很重要的,它允许点元字符与换行符以及所有其他字符匹配。
最后,您要确保匹配的是整个单词,而不仅仅是较长单词的片段,因此需要添加单词边界:

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

nimxete23#

看看这个例子:
我们有两个regexp a和b,我们希望两者都匹配,因此在伪代码中,它如下所示:

pattern = "/A AND B/"

无需使用and运算符即可写入,如下所示:

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

在pcre中:

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

regexp_match(pattern,data)
okxuctiv

okxuctiv4#

and运算符在regexp语法中是隐式的。
必须使用管道指定or运算符。
以下regexp:

var re = /ab/;

意思是字母 a 信呢 b .
它也适用于以下群体:

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

它指的是团体 co 和小组 de .
用or替换(隐式)和将需要以下行:

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

ep6jt1vc5#

您可以使用正则表达式来实现这一点,但可能需要使用其他正则表达式。例如,使用几个regexp并将它们组合在一个if子句中。
您可以使用标准regexp枚举所有可能的置换,如下所示(以任意顺序匹配a、b和c):

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

但是,如果您有多个术语,那么这会产生一个非常长且可能效率低下的regexp。
如果您使用的是一些扩展的regexp版本,比如perl或java,那么它们有更好的方法来实现这一点。其他答案建议使用正向前瞻操作。

disbfnqx

disbfnqx6#

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

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

b4wnujal7#

为什么不用awk呢?
有了awk正则表达式和or,事情就这么简单了

awk '/WORD1/ && /WORD2/ && /WORD3/' myfile
gz5pxeao

gz5pxeao8#

如果使用perl正则表达式,则可以使用正向前瞻:
例如

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

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

rvpgvaaj

rvpgvaaj9#

除了公认的答案之外
我将向你们提供一些实际的例子,让你们中的一些人更清楚地了解情况。例如,假设我们有三行文字:

[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]

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

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

注意,如果分隔表达式,则会得到不同的结果。
或者,您可能希望在标记之间选择一些文本。。。但不是标签!然后你可以使用:

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

对于本文本:

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

请参见演示

rkkpypqq

rkkpypqq10#

您可以通过管道将输出传输到另一个正则表达式。使用grep,您可以执行以下操作: grep A | grep B

zazmityj

zazmityj11#

顺序总是隐含在正则表达式的结构中。要实现所需的功能,必须将输入字符串与不同的表达式进行多次匹配。
使用单个regexp无法实现您想要的操作。

6xfqseft

6xfqseft12#

在正则表达式之外使用和。在php中,lookahead操作符似乎对我不起作用,相反,我使用了这个

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

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

b4qexyjb

b4qexyjb13#

((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. 将两者匹配,忽略大小写。

hpcdzsge

hpcdzsge14#

以下是“和”运算符的可能“形式”:
以下面的正则表达式为例:
如果要匹配不带“e”字符的单词,可以执行以下操作:

/\b[^\We]+\b/g
``` `\W` 表示不是“单词”字符。 `^\W` 表示“单词”字符。 `[^\We]` 表示“单词”字符,但不是“e”。
在行动中看到它:没有e的单词

### 正则表达式的“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]

相关问题