python - Grep 多层可迭代的字符串匹配(Python)

标签 python regex string search data-structures

假设我们有一个多层可迭代对象,在“最终”级别有一些字符串,是的,字符串是可迭代的,但我认为您明白我的意思:

['something', 
('Diff',
('diff', 'udiff'),
('*.diff', '*.patch'),
('text/x-diff', 'text/x-patch')),

('Delphi',
('delphi', 'pas', 'pascal', 'objectpascal'),
('*.pas',),
('text/x-pascal',['lets', 'put one here'], )),

('JavaScript+Mako',
('js+mako', 'javascript+mako'),
('application/x-javascript+mako',
'text/x-javascript+mako',
'text/javascript+mako')),
...
]

有什么方便的方法可以实现搜索,为我提供匹配字符串的索引?我想要一些像这样的东西(上面的列表是 data):

>>> grep('javascript', data)

它可能会返回 [ (2,1,1), (2,2,0), (2,2,1), (2,2,2) ]。也许我缺少一个类似的解决方案,它不返回任何类型的内容,但可以帮助我在 .... 字符串的可迭代对象的可迭代对象的多层列表中找到一些字符串。

我写了一点,但看起来幼稚和不雅所以我想我会在这里问。我想我可以继续按照我在这里开始的方式将异常嵌套到函数随后支持的级别数,但我希望得到一些简洁、抽象、pythonic 的东西。

import re

def rgrep(s, data):
    ''' given a iterable of strings or an iterable of iterables of strings,

    returns the index/indices of strings that contain the search string.

    Args::

        s - the string that you are searching for
        data - the iterable of strings or iterable of iterables of strings
    '''


    results = []
    expr = re.compile(s)
    for item in data:
        try:
            match = expr.search(item)
            if match != None:
                results.append( data.index(item) )

        except TypeError:
            for t in item:
                try:
                    m = expr.search(t)
                    if m != None:
                        results.append( (list.index(item), item.index(t)) )

                except TypeError:
                    ''' you can only go 2 deep! '''
                    pass

    return results

最佳答案

我将从 grepping 中分离递归枚举:

def enumerate_recursive(iter, base=()):
    for index, item in enumerate(iter):
        if isinstance(item, basestring):
            yield (base + (index,)), item
        else:
            for pair in enumerate_recursive(item, (base + (index,))):
                yield pair

def grep_index(filt, iter):
    return (index for index, text in iter if filt in text)

这样你就可以进行非递归和递归grepping:

l = list(grep_index('opt1', enumerate(sys.argv)))   # non-recursive
r = list(grep_index('diff', enumerate_recursive(your_data)))  # recursive

另请注意,我们在这里使用迭代器,必要时为更长的序列节省 RAM。

更通用的解决方案是给 grep_index 一个可调用的而不是字符串。但这对您来说可能不是必需的。

关于python - Grep 多层可迭代的字符串匹配(Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1584864/

相关文章:

python - Django 上的 Crispy Form VariableDoesNotExist

c# - 正则表达式到字符串或整数的转换

c# - 有人可以为我分解这个 lambda 表达式吗?

python - 尝试从 ubuntu crontab 运行 python 脚本

python - 在脚本调用之间保留 Python 变量

Python + PostgreSQL + 奇怪的ascii = UTF8编码错误

regex - 正则表达式非捕获组字符长度

python - 正则表达式匹配所有带有引号的句子

java - 在保持字典顺序的同时将新的 String 对象引入到字符串数组中的方法

带有 LineBreak 的 ASP.Net 文本从 Multi-Line-TextBox 保存在数据库中