python - 作为输入的单词列表上的正则表达式

标签 python regex list

例如,我有单词列表形式的句子

sentence = ['if', 'it', 'will', 'rain', ',', 'I', 'will', 'stay', 'at', 'home']

现在我想找到条件子句['if', 'it', 'will', 'rain']。原则上,我可以从句子创建一个字符串,例如s = ' '.join(sentence),我和使用正则表达式:

p = re.compile(r'(\bif\b[a-zA-z0-9\'\s]+)\s*(,*)\s*(then|,)')
for m in p.finditer(s):
    print m.start(1), m.end(1), '['+s[ m.start(1) : m.end(1) ]+']'

不需要判断正则表达式,它只是一个快速的草图:)。这给了我输出: 0 16 [if it will rain ]

到目前为止一切顺利。但现在我有点想念与原始列表的联系。正则表达式为我提供字符位置,而不是单词/标记位置。理想情况下,我会得到 0 和 3,这样我就知道条件子句是 sentence[0:3]。我确信我可以编写一个将字符位置映射到相应列表索引的方法,但我确信有更好的方法来完成这一切。

当然,我可以忽略正则表达式,循环遍历列表并得出正确的开始和停止条件。但常规目前看起来相当简洁,因为它们“隐藏”以使所需的条件明确。当条件子句由其他单词或短语表示时,它们还会简化情况,例如:

sentence = ['as', 'long', 'as', 'it', 'will', 'rain', ',', 'I', 'will', 'stay', 'at', 'home']

很容易用正则表达式反射(reflect)这一点,我认为使用循环有点烦人。

编辑:看到实际上没有一个非常简单的解决方案,我继续我的想法,在作为正则表达式字符串的句子和原始单词列表之间创建映射:

def join(self, word_list, separator=' '):
    mapping = []
    string = separator.join(word_list)
    for idx, word in enumerate(word_list):
    for character in word:
        mapping.append(idx)
    for character in separator:
        mapping.append(idx)
    return string, mapping

将此方法应用于我的输入string,mapping = join(sentence)结果:

mapping = [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9]

现在,如果正则表达式为我提供 016 作为匹配范围,我可以在原始句子中查找索引包含 mapping[0] = 0mapping[16] = 4 的列表。到目前为止,这似乎运作得相当不错。由于我使用字符串的正则表达式来进行匹配,因此我可以轻松支持条件子句的替代公式,例如:

CONDITIONAL_PHRASES = ['if', 'as long as', 'even if']
...
p = re.compile(r"((%s)\s+[a-zA-z0-9'\s]+)\s*(then|,)" % '|'.join(CONDITIONAL_PHRASES))

再说一次,我并不是说正则表达式已经很完美,但它支持同时使用多个句子,并为条件子句使用不同的指示词。

最佳答案

注意:-如果 if,then 中只出现一次句子

我对您的正则表达式进行了一些修改,以包含另一个捕获组

re.compile("((\\bif\\b)[a-zA-z0-9\\'\\s]+)\\s*(,*)\\s*(then|,)")

您可以使用 re.findall 来实现此目的

arr = re.findall(p, s)

arr[0][1] 包含第一个捕获组(字符串 if),arr[0][3] 包含第三个捕获组(字符串 then,)。您可以使用index来查找这2个的索引:

start = sentence.index(arr[0][1])
end = sentence.index(arr[0][3])

现在,您可以使用以下方式形成字符串

stri = ' '.join(sentence[start: end])

注 1:- 如果 ifthensentence (非重叠),您必须迭代所有元组

arr = re.findall(p, s)
pos = 0 #It stores the last occurrence of matched group
for i, x in enumerate(arr):
    start = sentence.index(x[1], pos)
    end = sentence.index(x[3], pos)
    stri = ' '.join(sentence[start: end])
    print(stri)
    pos = sentence.index(x[3], pos) + 1

<强> Ideone Demo

注 2:- 请记住,如果未找到字符串,index 会引发异常。在执行上述操作之前先处理一下

关于python - 作为输入的单词列表上的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36675451/

相关文章:

python - 如何在 Django 中通过 PUT 请求处理文件上传?

python - 在 manage.py 测试期间禁用日志记录?

python-3.x - python如何检查列表不包含任何值

javascript - Jquery - 根据后续后代中是否存在类来排除元素?

c# - 比较两个列表并返回不匹配的项目结果错误

python - 将 args 转换为平面列表?

python - 将 DataFrameGroupBy 对象中的每个分组列转换为列表

从 R 中的数据帧中删除特殊字符

javascript - 预先输入数字字符串的正则表达式

正则表达式查找匹配文件扩展名的文件,除非文件名包含字符串