【问题标题】:Python regex alternative matchesPython 正则表达式替代匹配
【发布时间】:2020-01-10 01:25:16
【问题描述】:

我有一个包含多个数字的变量。我想找到一个接一个只包含2个或多个重复数字的数字。这是 bash 等价物:

#!/usr/bin/env bash

numbers="1123456789
34312323445
6564323243
8975645345"

echo $numbers | egrep '0{2,10}|1{2,10}|2{2,10}|3{2,10}|4{2,10}|5{2,10}|6{2,10}|7{2,10}|8{2,10}|9{2,10}'

对于上述 bash 代码,我需要一个 Python 等效项。我尝试了以下方法,但没有按预期工作:

#!/usr/bin/env python3

import re

numbers = [1123456789, 34312323445, 6564323243, 8975645345]

pattern = re.compile('0{2,10}|1{2,10}|2{2,10}|3{2,10}|4{2,10}|5{2,10}|6{2,10}|7{2,10}|8{2,10}|9{2,10}')

for i in numbers:
    if pattern.match(str(i)):
        print(i)

bash sn-p 匹配112345678934312323445 但python sn-p 仅匹配11234567890,即只有在重复数字出现在数字的乞求时才会发生匹配。

【问题讨论】:

  • re.match 从头开始​​。 re.search 从任意位置开始。
  • echo -e 把戏真的让我畏缩。您首先要在字符串中添加文字换行符;外壳微不足道地允许这样做。然后,您当然不需要循环将echo 全部转至grep
  • @tripleee 完成。希望这能让你现在感觉好多了:D
  • 谢谢。不过,您现在可以简单地使用 echo "$numbers" | egrep ... 而不使用 for 循环。
  • 完成,删除 for 循环

标签: python regex bash


【解决方案1】:
import re

numbers = ["1123456789", "34312323445", "6564323243", "8975645345"]

pattern = r"((\d)\2+)"

for number in numbers:
    match = re.search(pattern, number)
    if match is not None:
        print(f"{number} has repeating digits ({match.group(1)})")

输出:

1123456789 has repeating digits (11)
34312323445 has repeating digits (44)

正则表达式模式的工作方式如下:

(\d) - 这是第 2 组。它捕获一个数字。

\2+ - 尝试一次或多次匹配第 2 组中的任何内容。

为了方便起见,整个东西都被包裹在另一个组(第 1 组)中。

您还可以使用re.findall 查找任何数字中的所有重复数字,而不仅仅是任何给定数字中的第一个匹配项:

import re

numbers = ["1123455556789", "34312323445", "6564323243", "8975645345"]

pattern = r"((\d)\2+)"

for number in numbers:
    for match_groups in re.findall(pattern, number):
        print(f"{number} has repeating digits ({match_groups[0]})")

输出:

1123455556789 has repeating digits (11)
1123455556789 has repeating digits (5555)
34312323445 has repeating digits (44)

【讨论】:

    【解决方案2】:

    在python中你可以这样做:

    >>> numbers = [1123456789, 34312323445, 6564323243, 8975645345]
    >>> reg = re.compile(r'([0-9])\1')
    >>> for i in numbers:
    ...     if reg.search(str(i)):
    ...             print i
    ...
    1123456789
    34312323445
    

    正则表达式详细信息:

    • ([0-9]): 匹配一个数字并在#1 组中捕获它
    • \1:反向引用第 1 组以确保我们有重复的数字

    顺便说一句,您的bash 代码也可以使用相同的捕获组和反向引用概念进行重构和简化:

    numbers="1123456789\n34312323445\n6564323243\n8975645345"
    printf '%b\n' "$numbers" | grep -E '([0-9])\1'
    

    1123456789
    34312323445
    

    【讨论】:

    • 不只是 bash 代码,甚至 python 正则表达式也不需要 2 个捕获组。就像我的回答一样,只要一个就足够了。
    【解决方案3】:

    对于pattern,请尝试以下操作:

    r".*(0{2,}|1{2,}|2{2,}|3{2,}|4{2,}|5{2,}|6{2,}|7{2,}|8{2,}|9{2,}).*"
    

    (假设您不想将重复次数限制为 10 次,而是设置为 2 次或更多次)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-12
      • 2022-08-10
      • 2022-11-29
      • 2012-05-16
      • 2016-07-01
      • 2013-09-22
      • 1970-01-01
      相关资源
      最近更新 更多