【问题标题】:Python Replace an Undetermined length of TextPython替换未确定长度的文本
【发布时间】:2012-03-01 07:30:11
【问题描述】:

我有一个这样的字符串:

Hi. My name is _John_. I am _20_ years old.

我想把它转换成这个:

Hi. My name is <b>John</b>. I am <b>20</b> years old.

我做了类似的事情,但没有运气。

import re
text = "Hi. My name is _John_. I am _20_ years old."
pattern = "(.*)(\_)(.*)(\_)(.*)"
re.sub(pattern, r'\1<b>\3</b>\5', text)
'Hi. My name is _John_. I am <b>20</b> years old.'

模式有什么问题?为什么看不到第一个粗体字?

任何帮助将不胜感激。 谢谢。

【问题讨论】:

    标签: python regex replace substitution


    【解决方案1】:

    改为:

    pattern = "_([^_]*)_"
    re.sub(pattern, r'<b>\1</b>', text)
    

    另见this example

    【讨论】:

      【解决方案2】:

      问题在于* 是贪婪的并且消耗尽可能多的字符(包括更多_)。要解决这个问题,您可以使用非贪婪替代品*?,如下所示:

      >>> pattern = r'_(.*?)_'
      >>> replacement = r'<b>\1</b>'
      >>> re.sub(pattern ,replacement, text)
      'Hi. My name is <b>John</b>. I am <b>20</b> years old.'
      

      注意re.sub 的行为类似于re.search 而不是re.match。也就是说,您可以使用仅部分匹配输入的模式(在这种情况下,只是一些由_ 包围的文本)而不是匹配整行的模式。

      【讨论】:

        【解决方案3】:

        问题是模式中的第一个 .* 正在吃掉最后一个可能匹配项左侧的所有内容。因此,据说*贪婪。使用非贪婪模式

        pattern='_(.+?)_'
        re.sub(pattern, r'<b>\1</b>', text)
        

        ? 使匹配非贪婪;尽可能短。 + 在两个下划线之间需要一个字符,以便将其替换为 &lt;b&gt;text&lt;/b&gt;。所以__ 将保持为__

        如果您希望 __ 变为 &lt;b&gt;&lt;/b&gt;,请使用 .*?

        【讨论】:

          【解决方案4】:

          您是否尝试过使用 String Templates ?他们是为这样的事情而建造的。简单的字符串替换。比使用正则表达式更干净、更优雅……

          import string
          
          new_style = string.Template('Hi. My name is $name. I am $age years old.')
          print new_style % {'name':'<b>John</b>', 'age':'<b>20</b>'} #produces what u want.
          

          有关字符串模板示例的更多信息,请查看activeState link

          【讨论】:

            【解决方案5】:

            这是因为模式是贪婪,第一个(.*)匹配从头到尾的文本到第三个_

            >>> re.match(pattern, text).groups()
            ('Hi. My name is _John_. I am ', '_', '20', '_', ' years old.')
            

            这是一个简化的、非贪婪的版本:

            >>> re.sub('_(.+?)_', r'<b>\1</b>', text)
            'Hi. My name is <b>John</b>. I am <b>20</b> years old.'
            

            【讨论】:

            • +1 如果您正在搜索字符串中间的内容(如.search.sub.findall,添加“之前的任何内容,之后的任何内容”都是没有意义的" 到正则表达式。
            【解决方案6】:

            这听起来非常像markdown syntax,所以如果您的目标是解析它,那么已经存在python library

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-09-23
            • 2021-05-09
            • 2022-10-14
            • 2015-12-19
            • 1970-01-01
            • 2012-07-06
            • 2017-05-03
            相关资源
            最近更新 更多