匹配两个或多个单词之间的字符串,无论顺序如何

问题描述

我需要一个与单词无关的正则表达式。例如,这些行应与标记的范围匹配,

A longword1 B longword2 C
  ^-------------------^

A longword2 B longword1 C
  ^-------------------^

这些不应该:

A longword1 B longword1 C
A longword2 B longword2 C
A longword1 B
A longword2 C

(A,B,C是填充符,它们基本上可以是任何文本)

可以仅使用替代,例如:\b((longword1).*?(longword2)|(longword2).*?(longword2))\b。但是正则表达式将阶乘增长,即三个词需要3!备用。也可以使用子例程,例如\b((?'A'longword1).*?(?'B'longword2')|(?P>B).*?(?P>A))\b。尽管简短,但我仍然需要包括其所有排列。

现在,我已经读过this postthis other one,但是被接受的答案并不能完全解决我的问题。使用\b(?=.*longword1)(?=.*longword2).*\b会匹配整行而不是我显示的范围。

我知道,如果我根据单词列表检查句子,会容易得多。但是我当前的用例阻止了它的实现。我只能使用正则表达式。

这里有一些链接可以证明我的意思:

已执行

错误:

有没有更简单的正则表达式来解决这个问题?

解决方法

您可以使用反向引用+子例程:

\b(longword1|longword2)\b.*?\b(?!\1\b)(?1)\b

将其扩展为三种选择:

\b(longword1|longword2|longword3)\b.*?\b(?!\1\b)((?1))\b.*?\b(?!(?:\1|\2)\b)(?1)\b

也请参见regex demothis regex demo。因此,单词列表将在第1组中,并且您只需要在后续子例程之前添加反向引用即可。

详细信息

  • \b(longword1|longword2)\b-整个单词,longword1longword2
  • .*?-除换行符以外的任何0个或多个字符,应尽可能少
  • \b-单词边界
  • (?!\1\b)-不能有与第1组匹配的相同文本,后接单词边界
  • (?1)-与第1组中的模式相同的子程序
  • \b-单词边界

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...