字符串简单替换

时间:2008-10-20 09:27:09

标签: python string

将大多数用户使用的简单正则表达式格式转换为正确的re python正则表达式字符串的最简单方法是什么?

作为一个例子,我需要转换它:

string = "*abc+de?"

到此:

string = ".*abc.+de.?"

当然我可以遍历字符串并按字符构建另一个字符串,但这肯定是一种低效的方法吗?

5 个答案:

答案 0 :(得分:5)

那些看起来不像你试图翻译的正则表达式,它们看起来更像unix shell globs。 Python已经有module这样做了。它不知道您使用的“+”语法,但我的shell也不知道,我认为语法是非标准的。

>>> import fnmatch
>>> fnmatch.fnmatch("fooabcdef", "*abcde?")
True
>>> help(fnmatch.fnmatch)
Help on function fnmatch in module fnmatch:

fnmatch(name, pat)
    Test whether FILENAME matches PATTERN.

    Patterns are Unix shell style:

    *       matches everything
    ?       matches any single character
    [seq]   matches any character in seq
    [!seq]  matches any char not in seq

    An initial period in FILENAME is not special.
    Both FILENAME and PATTERN are first case-normalized
    if the operating system requires it.
    If you don't want this, use fnmatchcase(FILENAME, PATTERN).

>>> 

答案 1 :(得分:2)

.replacing()每个通配符都是快捷方式,但是如果通配符字符串包含其他正则表达式特殊字符会怎么样?例如。搜索'my.thing *'的人可能并不意味着'。'匹配任何角色。在最糟糕的情况下,匹配组创建括号之类的东西可能会破坏你对正则表达式匹配的最终处理。

re.escape可用于将文字字符放入正则表达式。你必须首先拆分通配符。通常的技巧是使用带有匹配括号的re.split,从而生成[literal,wildcard,literal,wildcard,literal ...]形式的列表。

示例代码:

wildcards= re.compile('([?*+])')
escapewild= {'?': '.', '*': '.*', '+': '.+'}

def escapePart((parti, part)):
    if parti%2==0: # even items are literals
        return re.escape(part)
    else: # odd items are wildcards
        return escapewild[part]

def convertWildcardedToRegex(s):
    parts= map(escapePart, enumerate(wildcards.split(s)))
    return '^%s$' % (''.join(parts))

答案 2 :(得分:1)

您可能偶尔只会进行此替换,例如每次用户输入新的搜索字符串时,我都不会担心解决方案的效率。

您需要生成从“用户格式”转换为正则表达式所需的替换列表。为了便于维护,我将它们存储在字典中,就像@Konrad Rudolph一样,我只使用替换方法:

def wildcard_to_regex(wildcard):
    replacements = {
        '*': '.*',
        '?': '.?',
        '+': '.+',
        }
    regex = wildcard
    for (wildcard_pattern, regex_pattern) in replacements.items():
        regex = regex.replace(wildcard_pattern, regex_pattern)
    return regex

请注意,这仅适用于简单的字符替换,但如果需要,其他复杂代码至少可以隐藏在wildcard_to_regex函数中。

(另外,我不确定?是否应该转换为.? - 我认为普通通配符?为“正好一个字符”,所以它的替代应该是简单. - 但我跟随你的例子。)

答案 3 :(得分:0)

我使用replace

def wildcard_to_regex(str):
    return str.replace("*", ".*").replace("?", .?").replace("#", "\d")

这可能不是最有效的方法,但它对于大多数用途应该足够有效。请注意,某些通配符格式允许更难处理的字符类。

答案 4 :(得分:0)

这是执行此操作的Perl example。它只是使用一个表来用相应的正则表达式替换每个通配符构造。我之前已经完成了这个,但是在C中。移植到Python不应该太难。