根据一组单词

时间:2015-12-22 07:15:18

标签: python regex string

我有一个像这样的字符串列表,

['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people'] 

给定像['for', 'or', 'and']这样的关键字列表,我希望能够将列表解析为另一个列表,如果关键字列表出现在字符串中,则将该字符串拆分为多个部分。

例如,上面的集合将被分成

['happy_feet', 'happy_hats',  'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people']

目前我已经通过下划线拆分每个内部字符串,并且有一个for循环查找关键字的索引,然后通过下划线重新组合字符串。有更快的方法吗?

4 个答案:

答案 0 :(得分:6)

>>> [re.split(r"_(?:f?or|and)_", s) for s in l]
[['happy_feet'],
 ['happy_hats', 'cats'],
 ['sad_fox', 'mad_banana'],
 ['sad_pandas', 'happy_cats', 'people']]

要将它们合并为一个列表,您可以使用

result = []
for s in l:
    result.extend(re.split(r"_(?:f?or|and)_", s))

答案 1 :(得分:6)

>>> pat = re.compile("_(?:%s)_"%"|".join(sorted(split_list,key=len)))
>>> list(itertools.chain(pat.split(line) for line in data))

将为您提供的示例数据集提供所需的输出

实际上使用_分隔符你根本不需要按长度排序,所以你可以这样做

>>> pat = re.compile("_(?:%s)_"%"|".join(split_list))
>>> list(itertools.chain(pat.split(line) for line in data))

答案 2 :(得分:6)

您可以使用正则表达式:

from itertools import chain
import re

pattern = re.compile(r'_(?:{})_'.format('|'.join([re.escape(w) for w in keywords])))

result = list(chain.from_iterable(pattern.split(w) for w in input_list))

从您的关键字列表中动态创建模式。字符串'happy_hats_for_cats'分为'_for_'

>>> re.split(r'_for_', 'happy_hats_for_cats')
['happy_hats', 'cats']

但是因为我们实际上产生了一组备选方案(使用|元字符),您可以拆分任何关键字:

>>> re.split(r'_(?:for|or|and)_', 'sad_pandas_and_happy_cats_for_people')
['sad_pandas', 'happy_cats', 'people']

每个分割结果都会为您提供一个字符串列表(如果没有任何内容可以拆分,则只有一个字符串);使用itertools.chain.from_iterable()可以让我们将所有这些列表视为一个长迭代。

演示:

>>> from itertools import chain
>>> import re
>>> keywords = ['for', 'or', 'and']
>>> input_list = ['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people']
>>> pattern = re.compile(r'_(?:{})_'.format('|'.join([re.escape(w) for w in keywords])))    
>>> list(chain.from_iterable(pattern.split(w) for w in input_list))
['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people']

答案 3 :(得分:1)

另一种方法是,仅使用内置方法,用替换字符串替换每个字符串中['for', 'or', 'and']中所有出现的内容,例如_1_(它可以是任何字符串),然后在每次迭代结束时,拆分这个替换字符串:

l = ['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people'] 
replacement_s = '_1_'
lookup = ['for', 'or', 'and']
lookup = [x.join('_'*2) for x in lookup] #Changing to: ['_for_', '_or_', '_and_']
results = []
for i,item in enumerate(l):
    for s in lookup:
        if s in item:
            l[i] = l[i].replace(s,'_1_')
    results.extend(l[i].split('_1_'))

<强>输出:

['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people']