正则表达式,使用单词边界捕获而不停留在“点”和/或其他字符

时间:2018-02-25 18:23:55

标签: python regex

举个例如这样的字符串:
随机字,随机字符##?,一些点。用户名bob.1234其他内容

我目前正在使用此正则表达式来捕获用户名(bob.1234):

\busername (.+?)(,| |$)

但我的代码需要一个只有一个捕获组的正则表达式,因为python的 re.findall 会在有多个捕获组时返回不同的东西。这样的东西几乎可以工作,除了它会捕获用户名“bob”而不是“bob.1234”:

\busername (.+?)\b

有人知道是否有办法使用单词边界而忽略 dot 而不使用多个捕获组?

备注:

  • 有时在用户名
  • 后面有逗号
  • 有时在用户名
  • 后面有空格
  • 有时字符串以用户名
  • 结尾

1 个答案:

答案 0 :(得分:1)

\busername (.+?)(,| |$)模式包含2个捕获组,re.findall将在找到匹配后返回元组列表。见findall reference

  

如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。结果中包含空匹配,除非它们触及另一场比赛的开头。

所以,这里有三种方法:

  1. 使用(?:...)非捕获组而不是捕获组:re.findall(r'\busername (.+?)(?:,| |$)', s)。它将消耗,或空格,但由于只返回捕获的部分,并且没有预期的重叠匹配,所以没关系。
  2. 请使用积极的前瞻:re.findall(r'\busername (.+?)(?=,| |$)', s)。空格和逗号不会被消耗,这是与第一种方法的唯一区别。
  3. 您可以将(.+?)(,| |$)转换为与空格或逗号之外的一个或多个字符匹配的简单否定字符类[^ ,]+。如果,之后没有username或空格,它将匹配到字符串的结尾。