Python regex:仅在模式重复n次时匹配

时间:2019-04-15 10:49:16

标签: python regex

我有一个字符串:Name Mass From To Disulphide bond -2.02 97 144 Disulphide bond -2.02 111 158 Disulphide bond -2.02 121 174 Disulphide bond -2.02 125 176 Disulphide bond -2.02 85 174 Disulphide bond -2.02 10 176

我想拉出元组(97,144),(111,158),(121,174),(125,176),(85,174),(10,176)(即分别在-2.02之后的数字对)。

我只想匹配与此重复模式的确切数目匹配的字符串(即,“二硫键-2.02 X X”的相同单词模式精确重复6次)。文件中会有其他字符串具有完全相同的模式,但是重复的次数不超过6次(例如,文件中的另一个字符串可能是'Name Mass From To Disulphide bond -2.02 97 144 Disulphide bond -2.02 111 158 Disulphide bond -2.02 121 174',我不想与此匹配)。

我原本是在写这样的正则表达式:

six_regex = re.search(r'Name  Mass  From  To  Disulphide bond  -2.02  ([\d]+)  ([\d]+)  Disulphide bond  -2.02  ([\d]+)  ([\d]+)  Disulphide bond  -2.02  ([\d]+)  ([\d]+)  Disulphide bond  -2.02  ([\d]+)  ([\d]+)  Disulphide bond  -2.02  ([\d]+)  ([\d]+)  Disulphide bond  -2.02  ([\d]+)  ([\d]+)',mod_line)

我想知道是否有一种方法可以像这样编写正则表达式:

ix_regex = re.search(r' Disulphide bond  -2.02  ([\d]+)  ([\d]+)  ',mod_line)

我在其中添加“仅当上述短语匹配6次时匹配”。

我使用regex101.com来处理类似Disulphide bond -2.02 ([\d]+) ([\d\s]+){6}之类的东西,因为我在stackoverflow上的其他地方读到,将数字放在括号中可能是一个解决方案。但我似乎没有匹配项。

有人可以建议使用整洁的正则表达式吗,在这里我需要匹配一个重复的图案n次才能匹配。

3 个答案:

答案 0 :(得分:3)

您可以在python中使用以下代码:

Collection {#426 ▼
  #items: array:2 [▼
    0 => Bookings {#431 ▼
      #fillable: array:7 [▶]
      #primaryKey: "bookings_id"
      #connection: "mysql"
      #table: null
      #keyType: "int"
      +incrementing: true
      #with: []
      #withCount: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:10 [▼
        "bookings_id" => 1
        "users_id" => 1
        "schedules_id" => 6
        "buses_id" => 1
        "routes_id" => 3
        "seat" => "1"
        "price" => null
        "profile" => "pending"
        "created_at" => "2019-04-09 00:00:00"
        "updated_at" => "2019-04-09 00:00:00"
      ]
      #original: array:10 [▶]
      #changes: []
      #casts: []
      #dates: []
      #dateFormat: null
      #appends: []
      #dispatchesEvents: []
      #observables: []
      #relations: []
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #guarded: array:1 [▶]
    }
    1 => Bookings {#432 ▶}
  ]
} 

Code Demo

** RegEx详细信息:&& ​​

  • >>> import re >>> s = 'Name Mass From To Disulphide bond -2.02 97 144 Disulphide bond -2.02 111 158 Disulphide bond -2.02 121 174 Disulphide bond -2.02 125 176 Disulphide bond -2.02 85 174 Disulphide bond -2.02 10 176' >>> arr = re.findall(r'(?<=Disulphide bond -2.02 )(\d+) (\d+)', s) >>> if len(arr) == 6: ... print arr ... [('97', '144'), ('111', '158'), ('121', '174'), ('125', '176'), ('85', '174'), ('10', '176')] :向后查找表达式以断言我们在当前位置的左侧给出了字符串
  • (?<=Disulphide bond -2.02 ):匹配2个数字,在2个不同的捕获组中用2个空格隔开

答案 1 :(得分:2)

使用{6}量词是正确的想法。

您的问题不是将正确的样式分组((?:)-未选择分组)。

Name Mass From To (?:Disulphide bond -2\.02 ([\d]+) ([\d]+)\s*){6}应该可以解决问题。

说明

  • Name Mass From To-字符串的开头。
  • (?:-打开非选择组。
  • Disulphide bond -2\.02 ([\d]+) ([\d]+)\s*-您想要重复的模式
  • )-关闭非选择组。
  • {6}-重复非选择组六次。

答案 2 :(得分:1)

如果我理解正确,可以使用

reg1 = re.compile(r"(?:\s?Disulphide bond  -2.02  [\d]+  [\d]+\s?){6}")
matches = reg1.findall(your_string)

reg2 = re.compile(r"Disulphide bond  -2.02  ([\d]+)  ([\d]+)")
pairs = [reg2.findall(el) for el in matches]

首先,您要匹配所有重复六次的主题实例,然后从每个实例中提取配对