如何编写一个 Python 正则表达式来匹配包含单词和数字的字符串,排除仅包含数字的字符串?

ras*_*ool 3 python regex

我想编写一个正则表达式来匹配可能包含单词和数字而不仅仅是数字的字符串。

我使用了这个正则表达式[A-z+\d*],但它不起作用。

一些匹配的样本:

expression123
123expression
exp123ression
Run Code Online (Sandbox Code Playgroud)

不匹配的样本:

1235234567544
Run Code Online (Sandbox Code Playgroud)

你能帮我解决这个问题吗?先感谢您

Jan*_*Jan 7

环顾四周来救援!

^(?!\d+$)\w+$
Run Code Online (Sandbox Code Playgroud)

这使用负前瞻结构和锚点,请参阅regex101.com 上的演示


请注意,仅使用纯代码就可以获得相同的结果Python

samples = ["expression123", "123expression", "exp123ression", "1235234567544"]
 
filtered = [item for item in samples if not item.isdigit()]
print(filtered)

# ['expression123', '123expression', 'exp123ression']
Run Code Online (Sandbox Code Playgroud)

请参阅ideone.com 上的另一个演示

使用这两种方法,您都不会考虑像-1or 这样的输入字符串1.0(它们是允许的)。


测试

随着讨论的展开,这里有一个针对不同样本大小和表达式的小型测试套件:

import string, random, re, timeit


class RegexTester():
    samples = []
    expressions_to_test = {"Cary": "^(?=.*\D)\w+$",
                           "Jan": "^(?!\d+$)\w+$"}

    def __init__(self, sample_size=100, word_size=10, times=100):
        self.sample_size = sample_size
        self.word_size = word_size
        self.times = times

        # generate samples
        self.samples = ["".join(random.choices(string.ascii_letters + string.digits, k=self.word_size))
                        for _ in range(self.sample_size)]

        # compile the expressions in question
        for key, expression in self.expressions_to_test.items():
            self.expressions_to_test[key] = {"raw": expression, "compiled": re.compile(expression)}

    def describe_sample(self):
        only_digits = [item for item in self.samples if all(char.isdigit() for char in item)]
        return only_digits

    def test_expressions(self):

        def regex_test(samples, expr):
            return [expr.search(item) for item in samples]

        for key, values in self.expressions_to_test.items():
            t = timeit.Timer(lambda: regex_test(self.samples, values["compiled"]))

            print("{key}, Times: {times}, Result: {result}".format(key=key,
                                                                   times=self.times,
                                                                   result=t.timeit(100)))


rt = RegexTester(sample_size=10 ** 5, word_size=10, times=10 ** 4)
#rt.describe_sample()
rt.test_expressions()
Run Code Online (Sandbox Code Playgroud)

对于 10^5 的样本大小,10 的字大小给出了两个表达式的可比较结果:

Cary, Times: 10000, Result: 6.1406331
Jan, Times: 10000, Result: 5.948537699999999
Run Code Online (Sandbox Code Playgroud)

当您将样本大小设置为 10^4,单词大小设置为 10^3 时,结果是相同的:

Cary, Times: 10000, Result: 10.1723557
Jan, Times: 10000, Result: 9.697761900000001
Run Code Online (Sandbox Code Playgroud)

当字符串仅包含数字时(即样本仅由数字生成),您将得到显着差异:

Cary, Times: 10000, Result: 25.4842013
Jan, Times: 10000, Result: 17.3708319
Run Code Online (Sandbox Code Playgroud)

请注意,这是随机生成的文本,并且由于生成它的方法,字符串越长,它们仅由数字组成的可能性就越小。最终这将取决于实际的文本输入。