【问题标题】:Regex one-liner for matching only what comes after a certain word?正则表达式单行只匹配某个单词之后的内容?
【发布时间】:2016-01-16 08:44:57
【问题描述】:

我想从这样的列表中提取歌曲名称:'some text here, songs: song1, song2, song3, fro: othenkl' 并得到 ['song1', 'song2', 'song3']。所以我尝试在一个正则表达式中做到这一点:

result =  re.findall('[Ss]ongs?:?.*', 'songs: songname1, songname2,')
print re.findall('(?:(\w+),)*', result[0])

这完全匹配:['', '', '', '', '', '', '', 'songname1', '', 'songname2', ''](除了空字符串,但 nbd。

但我想在一行中完成,所以我做了以下:

print re.findall('[Ss]ongs?:?(?:(\w+),)*','songs: songname1, songname2,')

但我不明白为什么这无法捕获与上面两个正则表达式相同的内容:

['', 'name1', 'name2']

有没有办法在一行中完成这项工作?在这里简明扼要会很有用。谢谢。

【问题讨论】:

    标签: python regex python-2.7


    【解决方案1】:

    在这种情况下您不需要使用re.findall,您最好使用re.search 来查找歌曲序列,然后用逗号分割结果,。此外,您不需要使用字符类 [Ss] 来匹配可以使用忽略大小写标志 (re.I) 的大写字母:

    >>> s ='some text here, songs: song1, song2, song3, fro: othenkl'
    >>> re.search(r'(?<=songs:)(.+),', s,flags=re.I).group(1).split(',')
    [' song1', ' song2', ' song3']
    

    (?&lt;=songs:) 是一个正面的外观,这将使您的正则表达式引擎匹配songs: 前面的字符串,(.+), 将匹配songs: 之后的最大字符串,后面是逗号,即您的歌曲序列。

    除了在正则表达式末尾指定逗号之外,作为一种更通用的方法,您还可以根据以下事实捕获歌曲名称,即它们后面跟着这个模式 \s\w+:

    >>> re.search(r'(?<=songs:)(.+)(?=\s\w+:)', s).group(1).split(',')
    [' song1', ' song2', ' song3', '']
    

    【讨论】:

    • 所以,我猜你还是分两步做的,即使它是单行的。因为,您仍然需要将search 的结果除以split(',')
    • 请注意,如果捕获组没有找到任何匹配项,这将失败:re.search(...) 将返回None,上面的表达式不再有意义。
    【解决方案2】:

    不,您不能使用 re 模块以一种模式执行此操作。 您可以做的是使用 regex module 代替此模式:

    regex.findall(r'(?:\G(?!\A), |\msongs: )(\w++)(?!:)', s)
    

    其中\G 是上一次匹配之后的位置,\A 是字符串的开头,\m 是单词边界,后跟单词字符,++ 是所有格量词。

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 2018-12-21
      • 2019-11-12
      • 1970-01-01
      • 2011-10-13
      • 2017-07-21
      • 2021-09-21
      相关资源
      最近更新 更多