例如,我有单词列表形式的句子
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]
现在,如果正则表达式为我提供 0
和 16
作为匹配范围,我可以在原始句子
中查找索引包含 mapping[0] = 0
和 mapping[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:- 如果 if
和 、
或 then
在 sentence
(非重叠),您必须迭代所有元组
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/