Python 删除字母之间的符号

Python 删除字母之间的符号,python,regex,string,Python,Regex,String,我想从字符串中删除某些符号。我只想删除字母之间的符号。如果我的问题不够清楚,那么这里有一些例子: 符号是@31 输入 @@He11o Wor1d! !!T3ach !m3 @13! @@Heo Word! !!Tach !m3 @13! Data @@He11o Wor1d! !!T3ach !m3 @13! lala@@@@ Expected @@Heo Word! !!Tach !m3 @13! lala@@@@ Output @@Heo Word! !!Tach !m3 @13!

我想从字符串中删除某些符号。我只想删除字母之间的符号。如果我的问题不够清楚,那么这里有一些例子: 符号是
@31

输入

@@He11o Wor1d!
!!T3ach !m3
@13!
@@Heo Word!
!!Tach !m3
@13!
Data
@@He11o Wor1d!
!!T3ach !m3
@13!
lala@@@@ 

Expected
@@Heo Word!
!!Tach !m3
@13!
lala@@@@

Output
@@Heo Word!
!!Tach !m3
@13!
lala@@@@ 
预期产出

@@He11o Wor1d!
!!T3ach !m3
@13!
@@Heo Word!
!!Tach !m3
@13!
Data
@@He11o Wor1d!
!!T3ach !m3
@13!
lala@@@@ 

Expected
@@Heo Word!
!!Tach !m3
@13!
lala@@@@

Output
@@Heo Word!
!!Tach !m3
@13!
lala@@@@ 
你能给我指一下正确的方向吗?我不指望你为我做这件事。我知道这可以通过正则表达式和for循环来实现,但对于像我这样的初学者来说,正则表达式似乎有点困难。以下是我目前正在进行的工作:

string = '@@He11o Wor1d!'
string_copy = string
symbols = "@31!"
for char in symbols:
    string_copy = string_copy.replace(char, "")
我知道这个脚本取代了所有的符号

一开始肯定很可怕,但值得尝试学习它们,因为它们最终非常有用。在这种情况下,您需要的是:

import re
string = re.sub(r'([a-zA-Z])[@31!]+(?=[a-zA-Z])', r'\1', string)

类似于
str.replace
,但它使用正则表达式

[a-zA-Z]
匹配任何字母

[@31!]+
匹配一个或多个列出的符号

+ 使结果RE与前一个RE的1个或多个重复匹配

(?=[a-zA-Z])
是字母的先行断言。这意味着匹配后面有一个字母,但该字母不是匹配的一部分

(?=…) 匹配如果。。。匹配下一个,但不使用任何字符串。这称为前瞻断言。例如,Isaac(?=Asimov)仅当后跟“Asimov”时才与“Isaac”匹配

因此,
([a-zA-Z])[@31!]+(?=[a-zA-Z])
匹配一个字母,后跟列表中的一个或多个符号。此匹配后面跟着一个字母,但该匹配不包括该字母

\1
是对正则表达式中带括号的组的反向引用,在本例中为
[a-zA-Z]
。这就是我们想要用它来取代我们发现的东西

(字符串前面的
r
s将使其成为原始字符串,这在使用正则表达式时通常会有所帮助。)

编辑:

正如@ctwheels指出的那样:

string=re.sub(r')(?一开始肯定很吓人,但值得尝试学习它们,因为它们最终非常有用。在这种情况下,您需要的是:

import re
string = re.sub(r'([a-zA-Z])[@31!]+(?=[a-zA-Z])', r'\1', string)

类似于
str.replace
,但它使用正则表达式

[a-zA-Z]
匹配任何字母

[@31!]+
匹配一个或多个列出的符号

+ 使结果RE与前一个RE的1个或多个重复匹配

(?=[a-zA-Z])
是字母的先行断言。这意味着匹配后面跟着字母,但字母不是匹配的一部分

(?=…) 匹配if…匹配next,但不使用任何字符串。这称为前瞻断言。例如,Isaac(?=Asimov)仅当后跟“Asimov”时才会匹配“Isaac”

因此,
([a-zA-Z])[@31!]+(?=[a-zA-Z])
匹配一个字母,后面是列表中的一个或多个符号。此匹配后面是一个字母,但不包括该字母

\1
是对正则表达式中带括号的组的反向引用,在本例中为
[a-zA-Z]
。这就是我们要用它替换找到的

(字符串前面的
r
s将使其成为原始字符串,这在使用正则表达式时通常会有所帮助。)

编辑:

正如@ctwheels指出的那样:

string=re.sub(r'(?代码

输出
解释
  • (?代码
    

    输出
    解释

    • (?这是很难正确完成的。尽管我通常喜欢避免使用正则表达式,除非它们是必要的,但这确实是一种使工作更容易的情况。但无论如何,这里有一个非正则表达式的解决方案

      我们使用标准函数将输入字符串分为三类:“A”组包含字母,“S”组包含特殊符号,“O”组包含任何其他符号。然后我们扫描这些组,将它们复制到
      结果
      列表中,除非该组是“S”组,且其前面有一个“A”组,并且紧跟其后。最后,我们将复制的组重新加入到单个字符串中

      为了更容易检查下面的组,我们在组列表的末尾添加了一个“假”组
      ('O','')
      ,这样每个真实组都有一个下面的组

      from itertools import groupby
      
      symbols = '@31!'
      
      def keyfunc(c):
          if c in symbols:
              return 'S'
          elif c.isalpha():
              return 'A'
          else:
              return 'O'
      
      def remove_symbols(s):
          groups = [(k, ''.join(g)) for k, g in groupby(s, keyfunc)] + [('O', '')]
          result = []
          prev = 'O'
          for i, (k, g) in enumerate(groups[:-1]):
              # If a group of symbols has an alpha group on both sides, don't copy it
              if not (k == 'S' and prev == 'A' and groups[i+1][0] == 'A'):
                  result.append(g)
              prev = k
          return ''.join(result)
      
      # Test
      
      data = '''\
      @@He11o Wor1d!
      !!T3ach !m3
      @13!
      lala@@@@ 
      '''
      
      expected = '''\
      @@Heo Word!
      !!Tach !m3
      @13!
      lala@@@@
      '''
      print('Data')
      print(data)
      
      print('Expected')
      print(expected)
      
      print('Output')
      for s in data.splitlines():
          print(remove_symbols(s))   
      
      输出

      @@He11o Wor1d!
      !!T3ach !m3
      @13!
      
      @@Heo Word!
      !!Tach !m3
      @13!
      
      Data
      @@He11o Wor1d!
      !!T3ach !m3
      @13!
      lala@@@@ 
      
      Expected
      @@Heo Word!
      !!Tach !m3
      @13!
      lala@@@@
      
      Output
      @@Heo Word!
      !!Tach !m3
      @13!
      lala@@@@ 
      

      这是一个棘手的问题。尽管我通常倾向于避免使用正则表达式,除非它们是必要的,但这确实是一个使工作更容易的情况。但无论如何,这里有一个非正则表达式的解决方案

      我们使用标准函数将输入字符串分为三类:“A”组包含字母,“S”组包含特殊符号,“O”组包含任何其他符号。然后我们扫描这些组,将它们复制到
      结果
      列表中,除非该组是“S”组,且其前面有一个“A”组,并且紧跟其后。最后,我们将复制的组重新加入到单个字符串中

      为了更容易检查下面的组,我们在组列表的末尾添加了一个“假”组
      ('O','')
      ,这样每个真实组都有一个下面的组

      from itertools import groupby
      
      symbols = '@31!'
      
      def keyfunc(c):
          if c in symbols:
              return 'S'
          elif c.isalpha():
              return 'A'
          else:
              return 'O'
      
      def remove_symbols(s):
          groups = [(k, ''.join(g)) for k, g in groupby(s, keyfunc)] + [('O', '')]
          result = []
          prev = 'O'
          for i, (k, g) in enumerate(groups[:-1]):
              # If a group of symbols has an alpha group on both sides, don't copy it
              if not (k == 'S' and prev == 'A' and groups[i+1][0] == 'A'):
                  result.append(g)
              prev = k
          return ''.join(result)
      
      # Test
      
      data = '''\
      @@He11o Wor1d!
      !!T3ach !m3
      @13!
      lala@@@@ 
      '''
      
      expected = '''\
      @@Heo Word!
      !!Tach !m3
      @13!
      lala@@@@
      '''
      print('Data')
      print(data)
      
      print('Expected')
      print(expected)
      
      print('Output')
      for s in data.splitlines():
          print(remove_symbols(s))   
      
      输出

      @@He11o Wor1d!
      !!T3ach !m3
      @13!
      
      @@Heo Word!
      !!Tach !m3
      @13!
      
      Data
      @@He11o Wor1d!
      !!T3ach !m3
      @13!
      lala@@@@ 
      
      Expected
      @@Heo Word!
      !!Tach !m3
      @13!
      lala@@@@
      
      Output
      @@Heo Word!
      !!Tach !m3
      @13!
      lala@@@@ 
      

      你的输入是什么,输出是什么?写出来PLZ为什么不在上面加一个检查,确保它们跟在后面,后面有一个字母?不是说这是最好的方法,但对你来说,很明显我仍然建议正则表达式与
      str.replace()结合使用
      @DRPK这是前三行内容。在输入的左边,在
      =
      之后,对所需的输出进行签名出于好奇,否决票是怎么回事?请解释一下你的输入和输出是什么?请写出来。为什么不在上面加一个检查,确保它们都在后面,并且后面有一封信?不是这样吗你会是最好的wa