将正则表达式与\\ n匹配

时间:2014-09-05 22:57:19

标签: python regex

我有以下字符串:

>>> repr(s)
"    NBCUniversal\\n63  VOLGAFILM, INC               VOLGAFILMINC\\n64  Video Service Corp  

我希望在\\n之前匹配字符串 - 在空格字符之前的所有内容。输出应为:

['NBCUniversal', 'VOLGAFILMINC']

这是我到目前为止所做的:

re.findall(r'[^s].+\\n\d{1,2}', s)

这个正确的正则表达式是什么?

3 个答案:

答案 0 :(得分:1)

编辑:抱歉,我没有仔细阅读你的问题

如果您想在文字 \n之前立即找到所有字母组,re.findall是合适的。您可以通过以下方式获得所需的结果:

>>> import re
>>> s = "    NBCUniversal\\n63  VOLGAFILM, INC               VOLGAFILMINC\\n64  Video Service Corp  "
>>> re.findall(r'(?i)[a-z]+(?=\\n)', s)
['NBCUniversal', 'VOLGAFILMINC']

老答案:

re.findall不是合适的方法,因为您只需要一个结果(即一对字符串)。这里re.search方法更合适:

>>> import re
>>> s = "    NBCUniversal\\n63  VOLGAFILM, INC               VOLGAFILMINC\\n64  Video Service Corp  "
>>> res = re.search(r'^(?i)[^a-z\\]*([a-z]+)\\n[^a-z\\]*([a-z]+)', s)
>>> res.groups()
('NBCUniversal', 'VOLGAFILM')

注意:我假设第一个单词与文字 \n之间没有其他字符,但如果不是这样,则可以添加{{1}在模式中的[^a-z\\]*之前。

答案 1 :(得分:1)

如果你想修复现有的代码而不是替换它,那么你就是在正确的轨道上,你只是遇到了一些小问题。

让我们从你的模式开始:

>>> re.findall(r'[^s].+\\n\d{1,2}', s)
['    NBCUniversal\\n63  VOLGAFILM, INC               VOLGAFILMINC\\n64']

第一个问题是,.+会匹配它可以的所有内容,一直到最后一个\\n\d{1,2},而不仅仅是下一个\\n\d{1,2}。要解决此问题,请添加?以使其不贪婪:

>>> re.findall(r'[^s].+?\\n\d{1,2}', s)
['    NBCUniversal\\n63', '  VOLGAFILM, INC               VOLGAFILMINC\\n64']

请注意,我们现在应该有两个字符串。问题是,这些字符串不仅具有与.+?匹配的任何字符串,它们具有与整个模式匹配的任何字符串。要解决此问题,请将要捕获的部分包裹在()中以使其成为捕获组:

>>> re.findall(r'[^s](.+?)\\n\d{1,2}', s)
['   NBCUniversal', ' VOLGAFILM, INC               VOLGAFILMINC']

那更好,但它在左端还有一堆额外的东西。为什么?好吧,你在[^s]之后捕获了所有内容。这意味着除了s之外的任何字符。你几乎肯定意味着[\s],意思是空白类中的任何字符。 (注意\s已经是空白类,所以[\s],意味着由空白类组成的类是不必要的。)这样更好,但仍然只能匹配一个空格,而不是所有空间。并且它将匹配最早的空间,它仍然可以留下.+?匹配的东西,而不是最新的。因此,如果你想吸掉所有多余的空间,你需要重复它:

re.findall(r'\s+(.+?)\\n\d{1,2}', s)
['NBCUniversal', 'VOLGAFILM, INC               VOLGAFILMINC']

越来越近了......但.+?匹配任何,包括VOLGAFILMVOLGAFILMINC之间的空格,再次\s+正在进行匹配它可以的第一批空格,让.+?匹配之后的所有内容。

您可以使用前缀,但有一个更简单的解决方案。如果您不想在捕获组中使用空格,只需使用\S捕获一系列非空格而不是任何内容:

re.findall(r'\s+(\S+?)\\n\d{1,2}', s)
['NBCUniversal', 'VOLGAFILMINC']

请注意,一旦你完成了这项工作,\s+就不会再做任何事了,所以让我们放弃它:

re.findall(r'(\S+?)\\n\d{1,2}', s)
['NBCUniversal', 'VOLGAFILMINC']

我显然已经做出了一些适用于您的样本输入的假设,但对于实际数据可能不正确。例如,如果您有一个类似Weyland-Yutani\\n…的字符串,我假设您需要Weyland-Yutani,而不仅仅是Yutani。如果您有不同的规则,例如只有字母,只需将括号中的部分更改为符合该规则的内容,例如(\w+?)([A-Za-z]+?)

答案 2 :(得分:0)

假设输入实际上有序列\n(反斜杠后跟字母'n')而不是换行符,这将起作用:

>>> re.findall(r'(\S+)\\n', s)
['NBCUniversal', 'VOLGAFILMINC']

如果字符串实际包含换行符,则在正则表达式中将\\n替换为\n