Python 与Regex争用不同大小写的相邻字母

Python 与Regex争用不同大小写的相邻字母,python,regex,Python,Regex,我希望能够递归删除字符串中仅大小写不同的相邻字母,例如,如果s=AaBbccDd,我希望能够删除Aa-Bb-Dd,但保留cc 我可以使用列表递归地执行此操作: 我认为使用regex很难做到,但我正在努力: 对于测试字符串'fffAaaABbe',答案应该是'fffe',但我使用的正则表达式给出'fe' def test(line): res = re.compile(r'(.)\1{1}', re.IGNORECASE) #print(res.search(line))

我希望能够递归删除字符串中仅大小写不同的相邻字母,例如,如果s=AaBbccDd,我希望能够删除Aa-Bb-Dd,但保留cc

我可以使用列表递归地执行此操作:

我认为使用regex很难做到,但我正在努力:

对于测试字符串'fffAaaABbe',答案应该是'fffe',但我使用的正则表达式给出'fe'

def test(line):
    res = re.compile(r'(.)\1{1}', re.IGNORECASE)
    #print(res.search(line))
    while res.search(line):
        line = res.sub('', line, 1)
    print(line)
其工作方式是:

def test(line):
    result =''
    chr = list(line)
    cnt = 0
    i = len(chr) - 1

    while i > 0:
        if ord(chr[i]) == ord(chr[i - 1]) + 32 or ord(chr[i]) == ord(chr[i - 1]) - 32:
            cnt += 1
            chr.pop(i)
            chr.pop(i - 1)
            i -= 2
        else:
            i -= 1
    if cnt > 0: # until we can't find any duplicates.
        return test(''.join(chr))
    result = ''.join(chr)
    print(result) 

是否可以使用正则表达式进行此操作?

我建议使用另一种方法,即使用
groupby
对相邻的类似字母进行分组:

from itertools import groupby

def test(line):
    res = []
    for k, g in groupby(line, key=lambda x: x.lower()):
        g = list(g)
        if all(x == x.lower() for x in g):
            res.append(''.join(g))             
    print(''.join(res))
样本运行

>>> test('AaBbccDd')
cc
>>> test('fffAaaABbe')
fffe

re.IGNORECASE
不是解决此问题的方法,因为它将以相同的方式处理
aa
aa
aa
。从技术上讲,可以按照以下方式使用
re.sub

import re
txt = 'fffAaaABbe'
after_sub = re.sub(r'Aa|aA|Bb|bB|Cc|cC|Dd|dD|Ee|eE|Ff|fF|Gg|gG|Hh|hH|Ii|iI|Jj|jJ|Kk|kK|Ll|lL|Mm|mM|Nn|nN|Oo|oO|Pp|pP|Qq|qQ|Rr|rR|Ss|sS|Tt|tT|Uu|uU|Vv|vV|Ww|wW|Xx|xX|Yy|yY|Zz|zZ', '', txt)
print(after_sub)  # fffe
请注意,我明确定义了所有可能的字母对,因为到目前为止,我知道仅使用
re
模式无法表示“倒格字母”。也许其他用户能够提供更简洁的基于
re
的解决方案。

r'()\1{1}'
是错误的,因为它将匹配任何重复两次的字符,包括非字母字符。如果你想坚持字母,你不能用这个

但是,即使我们只做
r'[A-z]\1{1}'
,这仍然是不好的,因为您将匹配同一字母的任何序列两次,但它将捕获
xx
xx
——您不希望像在原始问题中所说的那样,用匹配的大小写匹配连续的相同字符

碰巧没有速记来方便地完成这项工作,但这仍然是可能的。您也可以只编写一个小函数,将其转换为速记

基于@Daweo的答案,你可以生成将相同字母对与非匹配案例匹配的相同字母对与非匹配案例匹配的相同字母对匹配所需的正则表达式模式,以生成匹配相同字母对与非匹配案例匹配的相同字母对所需的正则表达式模式,以得到《代码>aA| aA | aA | aA | aA | aA | aA | bB | bB | bB bB | bB | bB | bB | bB | bB | bB | bB 124| bB | bB| bB| bB| bB | bB | bB | bB | bB | bB | BB124| pP | pP | qQ | qQ | rR | rR | sS | sS | tT | tT | uU | vV | wW | xX | xX | yY | yY | zZ zZ:

重新导入
导入字符串
def continuevelettersnonmatchingcase():
#使用列表获取所有“xX | xX”
#并用“|”加入他们
返回'|'.join(['{0}{1}{1}{0}'。格式(s,t)\
#循环使用大小写字符
#步调一致
为s,t的拉链(
string.ascii_小写,
string.ascii(大写)])
def测试(线路):
res=re.compile(consuctionivelettersnommatchingcase())
打印(检索(行))
而res.search(行):
行=res.sub(“”,行,1)
打印(行)
打印(连续文本非匹配case())

AaA的输出是什么?在AaA输出上运行您的输入,但测试失败(“AaA”)应返回A,但不返回任何内容。此外,测试('AaAb')应返回'Ab'仅返回b.“。删除字符串中仅大小写不同的相邻字母”。这不是意味着
'AaA'
返回一个空字符串而
'AaAb'
只返回
'b'
?我的坏消息。我本应该说成对相邻的,但在回答问题的评论中我确实回避了这一点。有人问“AaA”的结果是什么,公平地说,我问题中发布的工作代码很明显是成对工作的。