【问题标题】:Regex to replace substring (if not the start of a word)正则表达式替换子字符串(如果不是单词的开头)
【发布时间】:2015-01-19 07:41:38
【问题描述】:

我正在处理像@Alice @ home 这样的推文。我想将用户提及的内容转换为普通词(例如@Alice => Alice)但保留个人@ 作为at 的代理项。所以简单地替换所有出现的@ 是行不通的。

我发现了单词边界的概念,但我无法让它们为此工作。一方面,

print re.sub(r'\b@\b', '', '@Alice @ home')

不会改变任何东西,而

print re.sub(r'\bAlice\b', '', '@Alice @ home')

结果为@​​987654328@。所以我假设 at 符号 (@) 不算作单词的一部分。

简而言之,我基本上是在寻找pattern 这样

print re.sub(pattern, '', '@Alice @ home')

输出Alice @ home。

感谢任何提示。

【问题讨论】:

    标签: python regex replace


    【解决方案1】:

    你可以玩\B和\b的边界

    >>> print re.sub(r'\B@\b', r'', '@Alice @ home')
    Alice @ home
    >>> print re.sub(r'\B@\b', r'', 'foo @Alice @ home')
    foo Alice @ home
    

    \B 匹配两个单词字符或两个非单词字符。所以上面正则表达式中的\B@ 匹配Alice 之前的@ 和另一个单独的@ 符号。 \b 匹配单词字符和非单词字符(反之亦然)。所以下面的\b 使模式只匹配第一个,因为第一个@ 本身后跟一个单词字符,即A。

    【讨论】:

    • 很好的答案。我在回答中根据 About-face 对其进行了投票。谢谢!
    【解决方案2】:
    (?:^|(?<=\s))@(?!\s)
    

    试试这个。这将仅从单词的开头替换@。如果@ 像as@sas 这样位于单词的中间,它将保存它。参见演示。

    https://regex101.com/r/tX2bH4/44

    re.sub(r'(?:^|(?<=\s))@(?!\s)','',s)
    

    【讨论】:

      【解决方案3】:

      初步回答

      试试下面的正则表达式:

      @(?! )
      

      这里有几个例子来说明它的表现:

      >>> print re.sub(r'@(?! )', '', '@Alice @ home')
      Alice @ home
      >>> print re.sub(r'@(?! )', '', 'Whatever @Alice @ home')
      Whatever Alice @ home
      

      您也可以使用a related regex fiddle 进行测试。

      关键点:

      • @ - at-sign
      • (?! ) – 否定前瞻,匹配除空格以外的任何内容(即后面没有空格)

      我个人觉得零宽度字边界断言(\b 和 \B)有点分散注意力,我更喜欢使用 zero-width lookarounds 来处理这类事情,但 TMTOWTDI。

      关于脸

      我想了更多(像往常一样),我发现无疑是零宽度词边界断言的简单性和字符串开头和结尾匹配的一个令人信服的案例。

      考虑一组更完整的推文:

      @Alice @ home
      Whatever @Alice @ home
      What're you lookin' @
      What're you lookin' @?
      

      事实证明,要使这些正确,需要一个更复杂的负前瞻,将我最初的正则表达式变成:

      @(?![ \W]|$)
      

      和以前一样,下面是它的执行示例:

      >>> print re.sub(r'@(?![ \W]|$)', '', '@Alice @ home')
      Alice @ home
      >>> print re.sub(r'@(?![ \W]|$)', '', 'Whatever @Alice @ home')
      Whatever Alice @ home
      >>> print re.sub(r'@(?![ \W]|$)', '', "What're you lookin' @")
      What're you lookin' @
      >>> print re.sub(r'@(?![ \W]|$)', '', "What're you lookin' @?")
      What're you lookin' @?
      

      和以前一样,您也可以使用a related regex fiddle 进行测试。

      但是像 Avinash Raj 所采用的词边界模式可以让这组更完整的可想象的推文变得正确......而且宣传更少:

      >>> print re.sub(r'\B@\b', '', '@Alice @ home')
      Alice @ home
      >>> print re.sub(r'\B@\b', '', 'Whatever @Alice @ home')
      Whatever Alice @ home
      >>> print re.sub(r'\B@\b', '', "What're you lookin' @")
      What're you lookin' @
      >>> print re.sub(r'\B@\b', '', "What're you lookin' @?")
      What're you lookin' @?
      

      如果您也喜欢,请使用 another related regex fiddle 进行测试。

      归根结底,这对我来说是一次很酷的学习经历,我可以质疑我更喜欢使用什么,我希望你也发现它是一样的:继续我们的词边界断言冒险! :)

      【讨论】:

        【解决方案4】:

        对我来说最简单的工作方式:

        >>> s = '@Alice @ home'
        >>> re.sub('\s@\s', ' at ', s).replace('@', '')
        'Alice at home'
        

        【讨论】:

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