【问题标题】:Extract items delimited with square brackets using python regular expressions使用python正则表达式提取用方括号分隔的项目
【发布时间】:2014-09-03 16:22:40
【问题描述】:

我正在尝试使用 python 正则表达式拆分由方括号分隔的单词/短语。我想拆分输出。条件是以方括号开头和结尾的文本部分将被拆分为不同的元素。

这是我目前所拥有的,但它不能正常工作:

import re
t="word1 word2 3456 [abc def] [ghi jkl] [1234] [-abcd] word 2345"
re.split("(\[)(.*)(\])+",t)

输出:

['word1 word2 3456 ',
'[',
'abc def] [ghi jkl] [1234] [-abcd',
']',
' word [xyz 2345']

我希望输出类似于:

['word1 word2 3456 ',
 '[abc def]',
 ' ',
 '[ghi jkl]',
 ' ',
 '[1234]',
 ' ',
 '[-abcd]',
 ' word [xyz 2345']

请注意,只有带有左方括号和右方括号的项目会被拆分。

我也试过这个:

re.split("(\[.*\])+",t)

但仅由第一个和最后一个方括号分开

['word1 word2 3456 ', '[abc def] [ghi jkl] [1234] [-abcd]', ' word [xyz 2345']

【问题讨论】:

  • 您可能想要re.findallre.finditer,而不是re.split

标签: python regex


【解决方案1】:

使用.+? 代替.*

>>> re.split("(\[.+?\])", t)
['word1 word2 3456 ', '[abc def]', ' ', '[ghi jkl]', ' ', '[1234]', ' ', '[-abcd]', ' word 2345']

【讨论】:

  • 没错!我忘记了re.split 保留了捕获组中的拆分器。好答案+1
  • 非常聪明的dav,我不知道这个+1
  • 不知道有分离器!还有:)
【解决方案2】:

你可以使用这个正则表达式来分割你的字符串:

\s(?=\[)|(?<=\])\s

Working demo

但由于它会拆分这些空间,因此会消耗它们,您生成的输出将是:

word1 word2 3456
[abc def]
[ghi jkl]
[1234]
[-abcd] word 2345

因此,作为一种解决方法,您可以使用上述正则表达式将匹配项替换为 ||| ||| 之类的自定义令牌,以生成如下内容:

word1 word2 3456||| |||[abc def]||| |||[ghi jkl]||| |||[1234]||| |||[-abcd]||| |||word 2345

然后你可以在你的自定义令牌||| 上使用 split 方法,它也会保留空格:

'word1 word2 3456'
' '
'[abc def]'
' '
'[ghi jkl]'
' '
'[1234]'
' '
'[-abcd]'
' '
'word '

【讨论】:

  • 这不太正确,因为它会删除空格,但它与 re.split 所获得的接近程度差不多
  • @AdamSmith 是的,你是对的。顺便说一句,我已经用一些解决方法更新了答案以获得 OP 输出......这只是提出一个想法
  • 看起来他想要什么,为什么不做一个zero-width split(?&lt;=])|(?=\[) 不过加:)
  • @Jonny5 哈哈!我没有考虑。我可以用它更新我的答案吗?
  • 哦哦! And now I see,Python re 显然不支持零宽度拆分(是否带有任何标志?)。 The manual says: Note that split will never split a string on an empty pattern match... 还有a discussion。所以最好切掉我对答案的想法:p
【解决方案3】:

试试这个:

re.findall(r"[^\]\[]*|\[[^\]\[]*?\]", t)

这将返回

['word1 word2 3456 ', '', 'abc def', '', ' ', '', 'ghi jkl', '', ' ', '', '1234', '', ' ', '', '-abcd', '', ' word 2345', '']

要删除空字符串,请执行以下操作:

list(filter(None, re.findall(r"[^\]\[]*|\[[^\]\[]*?\]", t)))

返回

['word1 word2 3456 ', 
 'abc def',
 ' ',
 'ghi jkl',
 ' ',
 '1234',
 ' ',
 '-abcd',
 ' word 2345']

解释正则表达式:

re.compile(r"""
    [^\]\[]*     # Zero or more characters that aren't [ or ]
    |            # OR
    \[           # a literal [
    [^\]\[]*?    # Zero or more characters that aren't [ or ]
    \]           # a literal ]""", re.X)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    相关资源
    最近更新 更多