【问题标题】:How to keep the sequence of regex match result如何保持正则表达式匹配结果的顺序
【发布时间】:2014-04-04 17:14:20
【问题描述】:
sentence = 'Alice was not a bit hurt, and she jumped up on to her feet in a moment.'
words = ['Alice','jumped','played']

为了匹配words 中的sentence,我使用了last post 答案中的代码

[w for w in words if re.search(r'\b{}\b'.format(re.escape(w)), sentence)]

这会得到我:

['Alice', 'jumped']

现在,如果words 列表以另一个序列(words = ['jumped','Alice','played'])给出,我想以它们在sentence 中出现的顺序显示匹配结果,即,仍然想要:

['Alice', 'jumped']

而不是

['jumped','Alice']

我应该如何修改代码?

【问题讨论】:

  • 如果句子是'Alice jumped over Alice',你想得到什么?

标签: python regex python-2.7


【解决方案1】:

一种方法是以句子为基础,过滤掉其他列表中的单词:

sentence_words = ['Alice','jumped','played']
words = ['jumped', 'Alice']
in_order = filter(set(words).__contains__, sentence_words)
# ['Alice', 'jumped']

或者:

word_set = set(words)
in_order = [word for word in sentence_words if word in word_set]

或者,您可以创建一个 word->last index seen 的查找,并使用:

lookup = {word: idx for idx, word in enumerate(sentence_words)}
words.sort(key=lookup.__getitem__)
['Alice', 'jumped']

也许将两者结合起来:

new_words = sorted((word for word in words if word in lookup), key=lookup.get)

【讨论】:

  • 感谢您的方法!
【解决方案2】:

你可以像这样构建你的模式:

 pattern = r'\b(?:' + '|'.join(words) + r')\b'

并使用 findall

 re.findall(pattern, sentence)

删除重复项:

list(set(re.findall(pattern, sentence)))

【讨论】:

  • 非常感谢!这对我有用。我是python的新手,你能告诉我模式构建中的哪一部分表示出现的顺序吗?
  • @ChuNan:模式中没有任何部分,唯一的事情是正则表达式引擎从左到右处理文本。你可以按照你想要的任何顺序给出一个单词列表,你会得到相同的结果(句子中的顺序)
  • 如 cmets 中所示的句子:Alice jumped over Alice,后面出现的同一个词 'Alice' 替换了 re.findall 中较早出现的那个。然后是['jump','Alice']。对吗?
  • @ChuNan 你得到['Alice', 'jumped', 'Alice'] 作为结果。
  • @ChuNan:Jerry 说的对,要避免重复吗?
猜你喜欢
  • 2012-06-17
  • 2016-11-10
  • 2015-07-06
  • 2013-09-27
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 2022-12-09
相关资源
最近更新 更多