Python 字符串模式识别/压缩

标签 python string compression pattern-recognition

我可以做基本的正则表达式,但这略有不同,即我不知道模式将是什么。

例如,我有一个类似字符串的列表:

lst = ['asometxt0moretxt', 'bsometxt1moretxt', 'aasometxt10moretxt', 'zzsometxt999moretxt']

在这种情况下,通用模式是两段通用文本:'sometxt''moretxt',开始并由长度可变的其他内容分隔。

公共(public)字符串和可变字符串当然可以以任何顺序出现在任何场合。

将字符串列表压缩/压缩为它们的公共(public)部分和个体变体的好方法是什么?

示例输出可能是:

c = ['sometxt', 'moretxt']

v = [('a','0'), ('b','1'), ('aa','10'), ('zz','999')]

最佳答案

此解决方案找到两个最长的公共(public)子串并使用它们来分隔输入字符串:

def an_answer_to_stackoverflow_question_1914394(lst):
    """
    >>> lst = ['asometxt0moretxt', 'bsometxt1moretxt', 'aasometxt10moretxt', 'zzsometxt999moretxt']
    >>> an_answer_to_stackoverflow_question_1914394(lst)
    (['sometxt', 'moretxt'], [('a', '0'), ('b', '1'), ('aa', '10'), ('zz', '999')])
    """
    delimiters = find_delimiters(lst)
    return delimiters, list(split_strings(lst, delimiters))

find_delimiters 和 friend 找到分隔符:

import itertools

def find_delimiters(lst):
    """
    >>> lst = ['asometxt0moretxt', 'bsometxt1moretxt', 'aasometxt10moretxt', 'zzsometxt999moretxt']
    >>> find_delimiters(lst)
    ['sometxt', 'moretxt']
    """
    candidates = list(itertools.islice(find_longest_common_substrings(lst), 3))
    if len(candidates) == 3 and len(candidates[1]) == len(candidates[2]):
        raise ValueError("Unable to find useful delimiters")
    if candidates[1] in candidates[0]:
        raise ValueError("Unable to find useful delimiters")
    return candidates[0:2]

def find_longest_common_substrings(lst):
    """
    >>> lst = ['asometxt0moretxt', 'bsometxt1moretxt', 'aasometxt10moretxt', 'zzsometxt999moretxt']
    >>> list(itertools.islice(find_longest_common_substrings(lst), 3))
    ['sometxt', 'moretxt', 'sometx']
    """
    for i in xrange(min_length(lst), 0, -1):
        for substring in common_substrings(lst, i):
            yield substring


def min_length(lst):
    return min(len(item) for item in lst)

def common_substrings(lst, length):
    """
    >>> list(common_substrings(["hello", "world"], 2))
    []
    >>> list(common_substrings(["aabbcc", "dbbrra"], 2))
    ['bb']
    """
    assert length <= min_length(lst)
    returned = set()
    for i, item in enumerate(lst):
        for substring in all_substrings(item, length):
            in_all_others = True
            for j, other_item in enumerate(lst):
                if j == i:
                    continue
                if substring not in other_item:
                    in_all_others = False
            if in_all_others:
                if substring not in returned:
                    returned.add(substring)
                    yield substring

def all_substrings(item, length):
    """
    >>> list(all_substrings("hello", 2))
    ['he', 'el', 'll', 'lo']
    """
    for i in range(len(item) - length + 1):
        yield item[i:i+length]

split_strings 使用分隔符拆分字符串:

import re

def split_strings(lst, delimiters):
    """
    >>> lst = ['asometxt0moretxt', 'bsometxt1moretxt', 'aasometxt10moretxt', 'zzsometxt999moretxt']
    >>> list(split_strings(lst, find_delimiters(lst)))
    [('a', '0'), ('b', '1'), ('aa', '10'), ('zz', '999')]
    """
    for item in lst:
        parts = re.split("|".join(delimiters), item)
        yield tuple(part for part in parts if part != '')

关于Python 字符串模式识别/压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1914236/

相关文章:

c# - 如何处理 ((List<string>)Session.Add ("")

java - 压缩和解压缩输入流中的字节 block

javascript - 闭包编译器导出所有原型(prototype)和静态方法

Python BeautifulSoup - 抓取 Div Spans 和 p 标签 - 以及如何获得 div 名称的精确匹配

python - 转置数据框中的子集列(不是 groupby,需要创建新列)

python - matplotlib 中的散点图

C - 使用 sprintf() 在字符串中添加前缀

python - 无法使用 ChoiceField 检查表单值

JAVA:空格分隔字符串中的所有非数字字符

android - 在 android 中使用 silicompressor 的视频压缩不起作用