【问题标题】:Python Regular expression: Find adjacent characters [duplicate]Python正则表达式:查找相邻字符[重复]
【发布时间】:2018-01-13 05:46:52
【问题描述】:

我需要得到一个包含字符串hello 中每两个相邻字符的列表,这样

['he', 'el', 'll', 'lo']

我以为我可以这样做

>>>import re
>>>re.findall(r'..', 'hello')
['he', 'll']

这不是我想要的。我需要使用正则表达式获取上面提到的列表

【问题讨论】:

  • @coldspeed:你不能把骗子和完全相同的问题联系起来吗? :Pstackoverflow.com/questions/11430863/…
  • 另一个完美的解决方案@Idlehands Cheerz
  • coldspeed 太急于将问题标记为重复。在我看来,将问题标记为重复需要更多时间来分析并找到最合适的重复。
  • 公平地说,这是他之前回答过的一个帖子(最近编辑过),所以他选择那个是很自然的。我只是在开玩笑,因为我在查找具有重叠匹配项的 re 时发现了另一个链接,并认为这很有趣,这是完全相同的问题。

标签: python regex


【解决方案1】:

好消息!您的问题是 exact duplicate of this one,它为您提供了所需的确切正则表达式:

>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']

阅读链接的线程以了解其背后的更多逻辑。

原答案:

不需要正则表达式。您可以为此使用列表推导。

h = 'hello'

a = [h[i:i+2] for i in range(len(h)-1)]

结果:

['he', 'el', 'll', 'lo']

编辑:RoadRunner 的 zip/map 解决方案更加优雅。也就是说,此解决方案是可扩展的,因此如果您愿意,您可以获得的不仅仅是 2 个相邻字符:

func = lambda my_list, n: [my_list[i:i+n] for i in range(len(my_list)-n+1)]

# OR, as RoadRunner suggested a cleaner read if you don't like lambdas:

def func(my_list, n): return [my_list[i:i+n] for i in range(len(my_list)-n+1)]

这会给你:

>>> func('hello', 2)
['he', 'el', 'll', 'lo']
>>> func('hello', 3)
['hel', 'ell', 'llo']
>>> func('hello', 4)
['hell', 'ello']

【讨论】:

  • 您的答案似乎比@RoadRunner 更好,因为我可以扩展它来解决我的实际问题。这里提出的问题不是确切的问题。但是为什么 re.findall(r'..', 'hello') 不会返回所有可能的两个相邻字符? as .. 表示 re 中每两个相邻的字符。你能用re来做吗?
  • 您所做的最后一次编辑正是我想要的,尽管我没有在问题中写下它。所以接受了你的答案。但是你能用 re 提供吗?
  • 我不是一个正则表达式用户,但似乎一旦re 匹配,它会从字符 after 继续匹配,这就是它继续的原因从 'he' 到 'll' 而不是 'el'。当我运行re.finditer(r'..','hello') 时,可迭代对象返回:<_sre.SRE_Match object; span=(0, 2), match='he'>, <_sre.SRE_Match object; span=(2, 4), match='ll'>。如您所见,跨度从 0,2 变为 2,4。
  • @skilledDt:基于re documentationfindall 返回非重叠匹配,这就是它不起作用的原因。 可能有一个用于重叠匹配的函数,但我在文档中没有看到它。
【解决方案2】:

这里不需要正则表达式,你可以使用zip()轻松做到这一点:

>>> s = "hello"
>>> [x + y for x, y in zip(s, s[1:])]
['he', 'el', 'll', 'lo']

甚至是 map() 的函数式方法:

>>> list(map(lambda x, y: x + y, s, s[1:]))
['he', 'el', 'll', 'lo']

如果您想要一种方法来处理任意数量的相邻字符,您可以尝试使用滑动窗口方法,该方法采用第一个 n 字符,然后弹出第一个字符,并重复此操作,直到不再有子字符串可以采用.

这是一个例子:

from collections import deque
from itertools import islice

def every_n(s, n):
    result = []

    items = deque(s)
    while len(items) >= n:
        result.append(''.join(islice(items, 0, n)))
        items.popleft()

    return result

其工作原理如下:

>>> print(every_n('hello', 2))
['he', 'el', 'll', 'lo']
>>> print(every_n('hello', 3))
['hel', 'ell', 'llo']
>>> print(every_n('hello', 4))
['hell', 'ello']
>>> print(every_n('hello', 5))
['hello']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多