忽略跟在数字后面的单词/非数字字符的正则表达式。

3
在Python中,我正在尝试匿名化或掩盖n个字符(从最后一个字符开始)。它可以用于匹配,但我想忽略同时包含数字的单词。
例如:
string = 'SomeText +12 555 660 000 f00b4r abc123'
digits = 5
repl_char = 'X'

regex = '[0-9\s\+]+'

for match in re.finditer(regex, string):
    phone_no = match.group()
    new_ph_no = ''
    i = 0
    if phone_no in ['', ' ']:
        pass
    else:
        for phone_digit in phone_no[::-1]:
            if phone_digit == ' ' or i >= digits:
                new_ph_no += phone_digit
            else:
                new_ph_no += repl_char
                i += 1
        string = string.replace(phone_no, new_ph_no[::-1])
    print(string)

目前输出 : 'SomeText +x2 555 6xx xxx fxxbxr abcxxx'

期望输出 : 'SomeText +12 555 6XX XXX f00b4r abc123'

我尝试在正则表达式中添加'[^?!a-zA-Z(0-9).*$]'以获得期望的输出,但是当我将字符串传递为'SomeText +12 555 660 000'时会失败。

我的意图是从任何类型的字符串中打印电话号码,并用“x”(或任何字符)替换n个数字。

如何打印所需的输出?


为什么在 660 的第二个数字上标记,而不是在 555 的第二个数字上标记? - anubhava
@anubhava,看到digits = 5,我认为数字部分的最后5位需要被替换,是吗? - Austin
是的,来自最后一个。 - san1512
2个回答

2

使用lambdare.sub中可以这样做:

最初的回答
>>> import re
>>> s = 'SomeText +12 555 660 000 f00b4r abc123'
>>> reg = r'(\b\d*(?: +\d+)*)((?: *\d){})(?! *\d)'
>>>
>>> print re.sub(reg.format('{5}'), lambda m: m.group(1) + re.sub(r'\d', 'X', m.group(2)), s)
SomeText +12 555 6XX XXX f00b4r abc123
>>>
>>> print re.sub(reg.format('{2}'), lambda m: m.group(1) + re.sub(r'\d', 'X', m.group(2)), s)
SomeText +12 555 660 0XX f00b4r abc123

细节:

  • 第一个正则表达式(\b\d*(?: +\d+)*)((?: *\d){5})(?! *\d)匹配前面是0或空格分隔数字,后面不跟可选空格和数字的最后5个数字。
  • re.sub中,我们使用lambda函数。
  • 在lambda函数的主体内,我们将每个数字替换为字母X

最初的回答:

该正则表达式(\b\d*(?: +\d+)*)((?: *\d){5})(?! *\d)匹配前面是0或空格分隔数字,后面不跟可选空格和数字的最后5个数字。在re.sub中,我们使用lambda函数,在lambda函数的主体内,我们将每个数字替换为字母X

但如果我把“5”换成“2”,它就不起作用了。>>> s ='SomeText +12 555 660 000 f00b4r abc123'>>> print(re.sub(r'(?: *\d){2}(?! *\d)', lambda m: re.sub(r'\d', 'X', m.group(0)), s))>>> SomeText +12 555 660 0XX fXXb4r abc1XX - san1512

1
如果号码始终以“+”开头,而您想获取不带“+”的完整号码,请使用:
\+(\d+(?:\s\d+)*)\b

我会尽力帮助您进行翻译。以下是需要翻译的内容:

它将返回(来自您的示例):12 555 660 000

在线查看:https://regex101.com/r/aEeIgK/2

解释:

  • \+ 从匹配的开始位置找到一个加号。将其转义为 +,成为正则表达式的量词符号。
  • \b 匹配单词边界(如果是以数字开头的混合字符串,则不会成为匹配的一部分)。
  • (\d+(?:\s\d+)*) 括号内的内容 (...) 是匹配的内容。
    • \d+ 匹配一个或多个数字的开头。 \d 表示数字;+表示匹配一个或多个。
    • (?:\s\d+)* 可选的(零个或多个)以空格 \s 开始,后跟数字的字符串。
    • (?:...) 是非匹配括号。
    • * 表示匹配零个或多个。
    • \s 表示空格(只有一个)。

SomeText +12 555 660 000 00b4r abc123 如果我去掉 'f' - san1512
也许您能解释一下吗? - san1512
@san1512 我在正则表达式的结尾处添加了单词边界,这样它就可以用于评论中的示例。为正则表达式添加了详细的解释。 - izem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接