我有一个这样的字符串:
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.'
模式有什么问题?为什么没有看到第一个粗体文字?
任何帮助将不胜感激。 感谢。
答案 0 :(得分:4)
问题是*
贪婪并消耗尽可能多的字符(包括更多_
)。要解决此问题,您可以使用非贪婪的替代*?
,如下所示:
>>> 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
。也就是说,您可以使用仅与输入部分匹配的模式(在这种情况下,只是一些由_
包围的文本)而不是与整行匹配的内容。
答案 1 :(得分:4)
答案 2 :(得分:3)
问题在于你模式中的第一个.*
正在吃最后一个可能匹配左边的所有内容。因此,据说*
贪婪。使用非贪婪模式
pattern='_(.+?)_'
re.sub(pattern, r'<b>\1</b>', text)
?
使匹配非贪婪;尽可能短。 +在两个下划线之间的东一个字符处需要,以便用<b>text</b>
替换它。因此__
将保持__
如果您希望__
成为<b></b>
,请使用.*?
答案 3 :(得分:3)
您是否尝试过使用String Templates?他们是为这样的东西而建造的。简单的字符串替换。很多清洁的地狱&amp;优雅而不是使用正则表达式...
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
答案 4 :(得分:2)
这是因为模式是贪心,第一个(.*)
匹配从开头一直到第三个_
的文字:
>>> 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.'
答案 5 :(得分:1)
这听起来非常像markdown syntax,所以如果您的目标是解析它,那么就已存在python library。