为什么此模式无法捕获python中所有重复的字符?

时间:2019-04-30 11:14:27

标签: python regex

问题是编写正则表达式模式以找出字符串中任何重复的字符。

For example:

The first target of "abcabcbb" is "abca" with repeated 'a'
The first target of "abba" is "abb" with repeated 'b'
...

我在python3中尝试了正则表达式模式。

当我将模式写为:

  
    
      

pair = re.compile(r“。*(。)。* \ 1”)

    
  

得到的结果是:

>>> s
['abcabcbb', '   ', 'abba', 'uqinntq']
>>> for ss in s:
...     res=pair.search(ss)
...     print(ss, res.group(), res.groups())
... 

abcabcbb abcabcbb ('b',)    ..............WRONG!
        (' ',)
abba abb ('b',)             ..............OK!
uqinntq uqinn ('n',)        ..............WRONG!

当我将模式更改为:

  
    
      

pair = re.compile(r“。*?(。)。*?\ 1”)

    
  

然后我得到了

abcabcbb abca ('a',)       ...............OK!
       (' ',)
abba abba ('a',)           ...............WRONG!
uqinntq uqinntq ('q',)     ...............WRONG!

我不知道为什么得到这些结果。在这种情况下如何编写正则表达式模式?

2 个答案:

答案 0 :(得分:0)

您得到的结果完全正确。

我们来看看您的第一个正则表达式.*(.).*\1和一些示例。

例如字符串是abcabcbb,在这里您得到b。让我们看看为什么。

您的正则表达式为.*(.).*\1,以.*开头,这很贪心,这意味着它会在提供匹配项的同时消耗尽可能多的字符。因此.*捕获abcabc,因为这是.*可以进行的最大捕获,并且(.)将匹配b,而.*将匹配空字符串,并且\1将再次匹配b,这就是匹配的结尾。因此,(.)在您获取时捕获了b。因此,这不是错误的匹配。

现在让我们以正则表达式的非贪婪版本为例,它是.*?(.).*?\1

让示例字符串为abba。这会给您a,让我们看看原因。

您的正则表达式.*?(.).*?\1开始与.*?匹配,因此这次尝试尽可能少地匹配,因此没有匹配,然后(.)匹配了a,然后是。*?匹配bb(请记住,它需要匹配最小值,但仍会生成匹配项),最后\1匹配最后的a。这样比赛就结束了,您在a中得到了(.),这是正确的。

答案 1 :(得分:0)

一个非正则表达式的解决方案是使用Counter来计数每个字符的频率。

.gap {
margin: 10px;
border: 1px solid black;
width: fit-content;
padding: 10px;
}

.row {
display: flex;
border: 1px solid black;
}

输出将是。

<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Startseite</title>

    <!-- Basic Icons-->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">


    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">

    <!-- Custom CSS -->
    <link rel="stylesheet" href="styletest.css">

</head>

<body>
    <div class="container">
        <div class="row">
            <div class="col-sm-3 gap">
                columns 1
            </div>
            <div class="col-sm-3 gap">
                columns 2
            </div>
            <div class="col-sm-3 gap">
                columns 3
            </div>
            <div class="col-sm-3 gap">
                columns 4
            </div>
            <div class="col-sm-3 gap">
                columns 5
            </div>
        </div>
    </div>
</body>

</html>