正则表达式有条件地提取命名组

时间:2013-08-27 07:32:18

标签: python regex

我需要编写python风格的正则表达式来有条件地提取字段。以下是我需要提取的两种类型的测试字符串:

 http://domain/string1/path/field_to_extract/path/filename
 http://domain/string2/path/90020_10029/path/filename

以下是我的要求:

  1. 对于string2,我们应该只选择第四个位置的数字,斜杠(/)和(_)之间。
  2. 对于其他人,我们应该在第四个位置的斜杠(/)之间选择整个文本。
  3. 我写了以下正则表达式:

    (?i)^(?:[^ ]*(?: {1,2})){6}(?:[a-z]+://)(?:[^ /:]+[^ /]/:]+[^ /]+/[^ /]+/)?(?:[^ /]+/){2}(?P<field_name>(?<=/string2/)(?:[^/]+/)([^_]+)|((?<!/string2/)(?:[^/]+/)([^/]+)))
    

    虽然条件提取似乎工作正常,但此正则表达式也匹配提取字段之前的字符串。例如,当在第一个测试字符串上使用时,此正则表达式匹配path/field_to_extract,而第二个匹配path/90020

    虽然我在必填字段之前添加了忽略组,但它似乎没有起作用。

    请帮我正确使用正则表达式。

3 个答案:

答案 0 :(得分:2)

如何使用split()代替complegex: -

s          = 'thelink'.split('/')
if len(s) > 4:
   string1or2 = s[3]
   field      = s[5]

   if string1or2 == 'string2':
       print field.split('_')[0]
else:
   raise ValueError("Incorrect URL")

答案 1 :(得分:2)

尝试使用模式'//[^/]+/[^/]+/[^/]+/(\d+(?=_)|[^/]+)'

答案 2 :(得分:0)

regex解决方案:

import re

urls = [
    r'''http://domain/string1/path/field_to_extract/path/filename''',
    r'''http://domain/string2/path/90020_10029/path/filename'''
]

for url in urls:
    print(re.search(r'(?<![:/])/(?:(string2)|[^/]*)/[^/]*/((?(1)[^_]*|[^/]*))', url).group(2))

<强>解释

(?<![:/])/ ::搜索不遵循其他斜杠或冒号的斜杠。

(?:(string2)|[^/]*)/ ::匹配文字“string2”或任何其他内容。如果是第一个,请将其保存为group-1,以便稍后执行条件 yes-no-pattern

[^/]*/ ::匹配路径的第二部分。没有意思。

((?(1)[^_]*|[^/]*)) ::如果存在group-1,则匹配到第一个_[^_]*)。否则匹配到下一个斜杠([^/]*)。

它产生:

field_to_extract
90020
相关问题