首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >正则表达式在python中括号内的所有字符周围添加空格。

正则表达式在python中括号内的所有字符周围添加空格。
EN

Stack Overflow用户
提问于 2018-02-18 04:56:53
回答 3查看 479关注 0票数 2

我的目标是在没有括号的情况下分开破折号。例如:“奎恩先生(美国侦探,情商),福尔摩斯先生(英国侦探)”

我希望结果是

奎恩先生(美国侦探、情商)、福尔摩斯先生(英国侦探)

我的代码是

代码语言:javascript
复制
re.sub(r'(.*)(\(.*)(-)(.*\))(.*)', r'\1\2 \3 \4\5', String)

然而,这段代码似乎只分开了最后一个破折号,出现在字符串的最后一个括号中。

它给出了“奎恩先生(美国侦探,EQ),福尔摩斯先生(英国侦探)”的结果。

有人能帮忙吗?我试图在这里找到,但我的代码似乎应该按照我预期的方式工作。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-02-18 05:29:28

这段代码的工作方式是将任务分成两部分。

  1. 它在字符串target中搜索由(...)封装的部分。
  2. 然后在每个发现的-中使用替换函数搜索并替换每个(...)中的每个替换函数

代码:

代码语言:javascript
复制
def expand_dashes(target):
    """
    replace all "-" with " - " when they are within ()

    target [string] - the original string

    return [string] - the replaced string

    * note, this function does not work with nested ()
    """
    return re.sub(r'(?<=\()(.*?)(?=\))', __helper_func, target)

def __helper_func(match):
    """
    a helper function meant to process individual groups
    """
    return match.group(0).replace('-', ' - ')

>>> x = "Mr. Queen (The-American-Detective, EQ), Mr. Holmes (The-British-Detective)"
>>> expand_dashes(x)
>>> "Mr. Queen (The - American - Detective, EQ), Mr. Holmes (The - British - Detective)"
票数 3
EN

Stack Overflow用户

发布于 2018-02-18 05:41:53

大多数正则表达式实现(包括Python)中的许多说明符表现得非常贪婪--也就是说,它们尽可能多地匹配输入字符串。因此,regex中的第一个.*将匹配所有输入字符串,但最后一组括号除外--第一个.*“吃掉”了它所能做的一切,同时留下足够的时间让整个正则表达式成功匹配。在这组圆括号中,首先有另一个.*,它类似地匹配它所能做的所有事情,而其余的正则表达式仍然有足够的时间来成功匹配-因此,除了最后一个破折号之外,最后一对括号中的所有破折号都是足够的。因此,替换只在最后一组括号中的最后一组破折号周围插入空格,因为regex只有一个不重叠的匹配:它匹配整个输入字符串,只是正则表达式中挑出短距之间括号的部分只包括最后的这种破折号。

要解决这个问题,您可能需要重新评估您的方法的某些部分,因为re.sub将取代不重叠的匹配,并且很难(我怀疑它甚至是可行的)构造一个正则表达式,它可以匹配给定的一对括号之间任意数目的破折号,并有一个相应的替换,在每个这样的破折号周围放置空格,并且仍然使每个匹配不重叠(使用一个能够捕捉任意数字组的regex系统,也许,但据我所知,Python的实现只捕捉到在给定匹配中任何可重复组((<group>)*(<group>)+等)的最后捕获组。用regex检查围绕虚线的括号需要在匹配中包含它们,这意味着匹配和执行单个短距之间括号的替换的正则表达式将具有重叠匹配,在同一对括号中有多个破折号。

渐进式方法虽然在实现上有点复杂,但可能是获得所需行为的更好方法。您可以使用re.split与适当的正则表达式将字符串拆分为括号大小的部分和中间的非括号部分,然后使用更简单的正则表达式(如r'([^-]*)(-)([^-]*)' )对插入部分执行正则表达式替换,以匹配任何破折号*,然后用新的括号部分重新组装完整的序列。这实际上打破了“单独捕获括号内的所有破折号”的问题--对于单个正则表达式来说,要将捕获正确分为两个问题:“查找括号大小的区段”和“单独捕获破折号”,这两个问题更容易解决。

*注意,这个regex建议使用字符类[^-],意思是“任何非-的字符”。这避免了.*当前正则表达式显示的问题,包括它匹配的内容中的破折号和“吃掉”除最后一个字符之外的所有字符,因为当下一个字符是-时,[^-]*被迫停止匹配。但是,在当前正则表达式中用.*替换[^-]*并不能解决这个问题,因为对于重叠的匹配,re.sub不会替换,就像相同括号内的多个破折号在这种情况下一样。

票数 1
EN

Stack Overflow用户

发布于 2018-02-18 05:43:48

尝试一种更简单的方法:

代码语言:javascript
复制
import re
s = "Mr. Queen (The-American-Detective, EQ), Mr. Holmes (The-British-Detective) "
s = re.sub(r'(\w+)(\-)(\w+)(\-)(\w+)', '\\1 \\2 \\3 \\4 \\5', s)
print(s)

产出:

代码语言:javascript
复制
Mr. Queen (The - American - Detective, EQ), Mr. Holmes (The - British - Detective)

这是working

  • \w本质上与[a-zA-Z0-9_]相同,即它匹配小写、大写、数字或下划线。
  • \--匹配。

因此,这个正则表达式匹配表单something-anything-anotherthing的任何字符串,并用something - anything - anotherthing替换它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48848594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档