【问题标题】:Regular expression for advanced string高级字符串的正则表达式
【发布时间】:2016-08-06 17:34:11
【问题描述】:

使用 Python 3.4 我想匹配可以具有以下格式的字符串:

s1 = "Germany  ; Federal Republic of Germany\tRépublique fédérale d'Allemagne\n"
s2 = "English  ; English language\tanglais\n"
s3 = "February\tfévrier\n"

注意两种语言之间是如何存在制表符的,如果一种语言中有多个单词,则它们除以" ; "(两个空格,分号,一个空格)。

我的目标是读取每种语言的第一个变量。所以我想匹配

  • s1("Germany", "République fédérale d'Allemagne")
  • s2("English", "anglais")
  • s3("February", "février")

如果\t的每一侧只有一对词汇或多个表达式。

问题是我找不到正确的模式。我尝试了多个表达式(使用search(),然后在返回的匹配对象上调用groups())似乎无法解决问题。

s1 示例:

  • r"([\w ]*)\t([\w ]*)" 找到 (' Federal Republic of Germany', 'République fédérale d')
  • r"(.*),?\t(.*),?" 找到 ('Germany ; Federal Republic of Germany', "République fédérale d'Allemagne")

这两个例子都没有达到我想要的效果。我不知道下一步该尝试什么。我确信有一种方法可以匹配 " ; " 之后的任何字符,直到 \t 但我现在不知道。

我们将不胜感激。

【问题讨论】:

  • 试试 r(\w*)[^\t]*;.*\t(.*)

标签: python regex match


【解决方案1】:

简单!

^(\S+)[^\t]*\t\s*(.+)\s*$

解释:

  • ^(\S+):获取字符串开头的所有非空白字符。
  • [^\t]*\t:忽略第一个制表符之前的所有内容 (\t)。
  • \s*(.+)\s*$: 获取字符串末尾的剩余部分,并带有修剪的左右空格。

【讨论】:

  • 虽然此代码可以回答问题,但提供有关它为什么和/或如何回答问题的额外上下文将显着提高其长期价值。请edit你的答案添加一些解释。
【解决方案2】:

你可以这样做:

res = s.strip().split('\t')
res[0] = res[0].split(';')[0].strip()

使用正则表达式:

import re

pat = re.compile(r'^\s*([^\s\t;]+(?:[^\S\t]+[^\s;]+)*)[^\S\t]*(?:;[^\t]*)?\t\s*(.*\S)')

m = pat.match(s)

[m.group(1), m.group(2)]

【讨论】:

    【解决方案3】:

    您要记住的重要一点是中间部分 - 由“;”分隔的可选第二位- 是可选的。正则表达式支持使用 ? 运算符的可选部分。

    你想捕捉第一个词,忽略中间部分,捕捉最后部分:

    (capture) optional? (capture)
    

    因为中间部分可能很复杂,所以您需要使用括号。但是您可以使用非捕获括号 - (?: non-captured pattern )

    (capture) (?: optional )? (capture)
    

    其余的你大概能猜出来:

    #! python3
    strings = [
        "Germany  ; Federal Republic of Germany\tRépublique fédérale d'Allemagne\n",
        "English  ; English language\tanglais\n",
        "February\tfévrier\n",
    ]
    
    import re
    
    for s in strings:
        m = re.match(r"^(\S+)(?:  ; [^\t]+)?\t([^\n]+)\n", s)
        print((m.group(1), m.group(2)))
    

    【讨论】:

    • 谢谢。我错过了一些关于非捕获模式的信息,这正是我正在寻找的。​​span>
    【解决方案4】:

    使用这个正则表达式:

    (\w*).*\t(.*)

    第一个捕获组将包含语言的单字名称,第二个捕获组将包含消息。

    Regex101 Tested

    【讨论】:

    • 我已经更新了我的答案。我之前的“Regex101 测试”是错误的。
    【解决方案5】:

    试试这个正则表达式:([^;\t]+)[;]*[^\t]*([^\n]*)

    结果将包含空白填充,您可能希望将其删除。

    说明

    • ([^;\t]+) 捕获不是\t; 的字符
    • [;]* 0 个或多个 ;
    • [^\t]* 0 个或多个而不是 \t 个字符
    • ([^\n]*) 捕获 0 个或多个而不是 \n 字符

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-28
      • 1970-01-01
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多