提问者:小点点

regex来查找一对相邻的数字,它们周围有不同的数字


我是一个正则表达式的初学者,我正在试着做一个表达式,找出是否有两个相同的数字紧挨着,而这对数字后面和前面的数字是不同的。

例如,

123456678应该匹配,因为存在双6,

1234566678不应匹配,因为没有具有不同周围数字得double。 12334566应该匹配,因为有两个3。

到目前为止,我只得到了1,只要double不在字符串的开头或结尾,我可以通过在开头和结尾添加一个字母来处理这个问题。

^.*([^1]11[^1]).*$

我知道我可以使用[0-9]来代替1,但问题是它们都是同一个数字。

谢谢!


共3个答案

匿名用户

对于regex,您只能使用(*skip)(*fail)谓词对PyPiregex模块执行此操作:

import regex
rx = r'(\d)\1{2,}(*SKIP)(*F)|(\d)\2'
l = ["123456678", "1234566678"]
for s in l:
  print(s, bool(regex.search(rx, s)) )

请参阅Python演示。 输出:

123456678 True
1234566678 False

正则表达式详细信息

  • (\d)\1{2,}(*skip)(*f)-一个数字,然后出现两个或多个相同的数字
  • -或
  • (\d)\2-一个数字,然后是同一个数字。

重点是匹配所有相同的3个或更多数字的块并跳过它们,然后匹配一个两个相同数字的块。

请参阅正则表达式演示。

匿名用户

您可以按如下方式测试字符串:

import re

r = r'(\d)(?!\1)(\d)\2(?!\2)\d'
arr = ["123456678", "1123455a666788"]
for s in arr:
  print(s, bool(re.search(r, s)) )

显示

123456678 True
1123455a666788 False

运行Python代码

下面指向regex101.com的链接为PCRE(PHP)引擎使用等效的regex。 我将其包括在内,以便读者检查regex的每个部分是如何工作的。 (左右移动光标,查看详细说明。)

启动PCRE引擎!

两个发动机都执行以下操作。

(\d)    : match a digit and save to capture group 1 (preceding digit)
(?!\1)  : following character cannot equal capture group 1
(\d)    : match a digit in capture group 2 (first digit of pair)
\2      : match content of capture group 2 (second digit of pair)
(?!\2)  : following character cannot equal cap group 2
\d      : match a digit

您可以使用下面的正则表达式和Python的regex模块来获取匹配的数字对。

r'(\d)(?!\1)\K(\d)\2(?=\d)(?!\2)'

发动机

regex引擎执行以下操作。

(\d)    : match a digit and save to capture group 1 (preceding digit)
(?!\1)  : following character cannot equal capture group 1
\K      : forget everything matched so far and reset start of match
(\d)    : match a digit in capture group 2 (first digit of pair)
\2      : match content of capture group 2 (second digit of pair)
(?=\d)  : following character must be a digit
(?!\2)  : following character cannot equal cap group 2

(?=\d)(?!\2)可以替换为:

(?!\2|$|\D)

匿名用户

受Wiktor stribi zew答案的启发,使用re交替的另一种变体是检查捕获组的存在,该捕获组包含两个未被相同数字包围的相同数字的正匹配。

在这种情况下,检查组3。

((\d)\2{2,})|\d(\d)\3(?!\3)\d

Regex演示Python演示

  • (捕获组1
    • (\d)\2{2,}捕获组2,匹配1个数字并重复该数字2次

    例如

    import re
    
    pattern = r"((\d)\2{2,})|\d(\d)\3(?!\3)\d"
    strings = ["123456678", "12334566", "12345654554888", "1221", "1234566678", "1222", "2221", "66", "122", "221", "111"]
    
    for s in strings:
        match = re.search(pattern, s)
        if match and match.group(3):
            print ("Match: " + match.string)
        else:
            print ("No match: " + s)
    

    输出量

    Match: 123456678
    Match: 12334566
    Match: 12345654554888
    Match: 1221
    No match: 1234566678
    No match: 1222
    No match: 2221
    No match: 66
    No match: 122
    No match: 221
    No match: 111
    

    例如,如果只有2位或3位也可以匹配,则可以检查组2

    (\d)\1{2,}|(\d)\2
    

    Python演示