Python 正则表达式——如何允许非相邻的替换?

Python 正则表达式——如何允许非相邻的替换?,python,regex,string,Python,Regex,String,在翻译测试应用程序(Python)中,我需要一个正则表达式,它可以接受以下两个字符串之一: a = "I want the red book" b = "the book which I want is red" 到目前为止,我使用的是这样的东西: ^(the book which )*I want (is |the )red (book)*$ 这将同时接受字符串a和字符串b。但它也将接受不包含两个可选子字符串之一的字符串: sub1 = (the book which ) sub2 = (

在翻译测试应用程序(Python)中,我需要一个正则表达式,它可以接受以下两个字符串之一:

a = "I want the red book"
b = "the book which I want is red"
到目前为止,我使用的是这样的东西:

^(the book which )*I want (is |the )red (book)*$
这将同时接受字符串a和字符串b。但它也将接受不包含两个可选子字符串之一的字符串:

sub1 = (the book which )
sub2 = (book)
我如何指示这两个子串中的一个必须存在,即使它们不是相邻的


我意识到在这个例子中,通过测试以“或”
|
分隔的更长的备选方案,可以很容易地避免问题。这是一个简化的问题示例,我正在处理的实际用户输入很难避免。

这看起来像是一个使用正则表达式可能比使用正则表达式更好解决的问题

但是,适用于原始问题中特定示例的正则表达式如下所示:

^(the book which )*I want (is |the )red((?(1)(?: book)*| book))$

对于字符串“I want the red”(缺少所需的子字符串“books which”和“book”),这将失败。这使用了(?(id/name)yes pattern | no pattern)语法,该语法允许基于先前匹配组的存在进行替换。

这似乎是一个使用正则表达式可能比使用正则表达式更好解决的问题

但是,适用于原始问题中特定示例的正则表达式如下所示:

^(the book which )*I want (is |the )red((?(1)(?: book)*| book))$
对于字符串“I want the red”(缺少所需的子字符串“books which”和“book”),这将失败。这使用(?(id/name)yes pattern | no pattern)语法,该语法允许基于先前匹配的组的存在进行替换

我如何指示这两个子字符串中的一个必须存在, 即使它们不是相邻的

我想这是你的核心问题

解决方案是两个正则表达式。我不明白为什么人们觉得一旦说
import re
正则表达式必须是一行

首先测试一个正则表达式中的第一个子字符串,然后使用另一个正则表达式测试另一个子字符串。从逻辑上把这两个结果结合起来

import re

regx1 = re.compile('^(the book which )*I want (is |the )red'   '((?(1)|(?: book)))$')

regx2 = re.compile('^(the book which )*I want (is |the )red'   '((?(1)(?: book)*|(?: book)))$')




for x in ("I want the red book",
          "the book which I want is red",
          "I want the red",
          "the book which I want is red book"):
    print x
    print regx1.search(x).groups() if regx1.search(x) else 'No match'
    print regx2.search(x).groups() if regx2.search(x) else 'No match'
    print
我如何指示这两个子字符串中的一个必须存在, 即使它们不是相邻的

我想这是你的核心问题

解决方案是两个正则表达式。我不明白为什么人们觉得一旦说
import re
正则表达式必须是一行

首先测试一个正则表达式中的第一个子字符串,然后使用另一个正则表达式测试另一个子字符串。从逻辑上把这两个结果结合起来

import re

regx1 = re.compile('^(the book which )*I want (is |the )red'   '((?(1)|(?: book)))$')

regx2 = re.compile('^(the book which )*I want (is |the )red'   '((?(1)(?: book)*|(?: book)))$')




for x in ("I want the red book",
          "the book which I want is red",
          "I want the red",
          "the book which I want is red book"):
    print x
    print regx1.search(x).groups() if regx1.search(x) else 'No match'
    print regx2.search(x).groups() if regx2.search(x) else 'No match'
    print
结果

I want the red book
(None, 'the ', ' book')
(None, 'the ', ' book')

the book which I want is red
('the book which ', 'is ', '')
('the book which ', 'is ', '')

I want the red
No match
No match

the book which I want is red book
No match
('the book which ', 'is ', ' book')
编辑

你的正则表达式模式

^(the book which )*I want (is |the )red (book)*$
由于最后一个空格,无法正确匹配所有句子

一定是

'^(the book which )*I want (is |the )red( book)*$'
结果

I want the red book
(None, 'the ', ' book')
(None, 'the ', ' book')

the book which I want is red
('the book which ', 'is ', '')
('the book which ', 'is ', '')

I want the red
No match
No match

the book which I want is red book
No match
('the book which ', 'is ', ' book')
编辑

你的正则表达式模式

^(the book which )*I want (is |the )red (book)*$
由于最后一个空格,无法正确匹配所有句子

一定是

'^(the book which )*I want (is |the )red( book)*$'

你说你的实际问题比你在这里给出的单个例子更复杂。这使得你很难真正回答你的问题。您是否考虑过使用类似于NLTK的东西以最通用的方式()来实现这一点?就你的目的而言,这可能是过分的,但同样,如果没有问题中的更多细节,这是不可能说出来的。如果这是问题的一个微不足道的例子,我对你提出的问题给出的任何解决方案都可能无法解决你的实际问题,因此将浪费我和你的时间。请给出一个真实的例子,我们也许能够解决这个问题(甚至可能不涉及正则表达式)。另请参见。但我认为我的问题很清楚——有没有一种方法可以要求在regex中使用两个非相邻的选项之一。你能回答我提出的问题吗,而不是让我举一个更复杂的例子?“或”运算符是定义所需备选方案的唯一方法吗?@Johnsyweb IMHO,你说得对,这可能是一个XY问题。但“可能”的意思可能是;在目前的情况下,我认为这只是一个假设。另一个假设是:我们可能认为,在语言学领域做事情的提问者,这是一门很难的学科,他有足够的概念化和推理能力,知道对简化问题的解决是否有助于他解决复杂问题,以及解决复杂问题是否值得。XY问题的可能性不允许认为所有的简化问题都是Y。@monotasker“我认为我的问题很清楚”是这样的。“或”运算符是定义所需备选方案的唯一方法吗?”不,也有条件备选方案:请参见
(?(id/name)yes pattern | No pattern)
,您说您的实际问题比这里给出的单个示例更复杂。这使得你很难真正回答你的问题。您是否考虑过使用类似于NLTK的东西以最通用的方式()来实现这一点?就你的目的而言,这可能是过分的,但同样,如果没有问题中的更多细节,这是不可能说出来的。如果这是问题的一个微不足道的例子,我对你提出的问题给出的任何解决方案都可能无法解决你的实际问题,因此将浪费我和你的时间。请给出一个真实的例子,我们也许能够解决这个问题(甚至可能不涉及正则表达式)。另请参见。但我认为我的问题很清楚——有没有一种方法可以要求在regex中使用两个非相邻的选项之一。你能回答我提出的问题吗,而不是让我举一个更复杂的例子?“或”运算符是定义所需备选方案的唯一方法吗?@Johnsyweb IMHO,你说得对,这可能是一个XY问题。但“可能”的意思可能是;在目前的情况下,我认为这只是一个假设。另一个假设是:我们可能认为,在语言学领域做事情的提问者,这是一门很难的学科,他已经