【问题标题】:A pythonic way to insert a space before capital letters but not insert space between an Abbreviation在大写字母之前插入空格但不在缩写之间插入空格的pythonic方法
【发布时间】:2019-10-14 00:35:51
【问题描述】:

我有一个文件,我正在通过 python 脚本更改其格式。我在这个文件中有几个驼峰式字符串,我只想在大写字母之前插入一个空格 - 所以“WordWordWord”变成了“Word Word Word”,但我也有一些缩写,比如文本“总经理或副总裁”。

我在这篇文章中找到了 David Underhill 的答案:

A pythonic way to insert a space before capital letters

虽然这个答案可以帮助我不在“DaveIsAFKRightNow!Cool”等文本中的缩写之间插入空格

但它肯定会在“VP”中的 V 和 P 之间插入一个空格。

我只有 25 点经验值,无法对现有帖子发表评论,我别无选择,只能针对此类问题创建另一个帖子。

我不太擅长 RegEx,也不知道如何处理这种情况。

我试过这个:

re_outer = re.compile(r'([^A-Z ])([A-Z])')
re_inner = re.compile(r'(?<!^)([A-Z])([^A-Z])')
re_outer.sub(r'\1 \2', re_inner.sub(r' \1\2', 'DaveIsAFKRightNow!Cool'))

它给了我“戴夫现在是 AFK!酷'

我的文本示例是这样的:

General Manager or VP Torrance, CARequired education

我希望输出为:General Manager or VP Torrance, CA Required education

我得到的输出是:General Manager or V P Torrance, CA Required education

【问题讨论】:

标签: regex python-3.x


【解决方案1】:

您可以将替换替换为首先在大写字母之前插入空格,前面有除大写字母和空格之外的字符,然后在以 1+ 个大写字母开头、后面跟着一个大写和一个小写的单词之前附加一个空格信:

import re
re_outer = re.compile(r'([^A-Z ])([A-Z])')
re_inner = re.compile(r'\b[A-Z]+(?=[A-Z][a-z])')
print(re_inner.sub(r'\g<0> ', re_outer.sub(r'\1 \2', 'DaveIsAFKRightNow!Cool')))
# => Dave Is AFK Right Now! Cool
print(re_inner.sub(r'\g<0> ', re_outer.sub(r'\1 \2', 'General Manager or VP Torrance, CARequired education'))) 
# => General Manager or VP Torrance, CA Required education

Python demo

\b[A-Z]+(?=[A-Z][a-z]) 正则表达式匹配

  • \b - 字边界
  • [A-Z]+ - 1+ 个大写字母
  • (?=[A-Z][a-z]) - 后跟一个大写字母和一个小写字母。

请注意,\g&lt;0&gt; 在替换模式中插入整个匹配项。

【讨论】:

    【解决方案2】:

    作为替代方案,您可以使用带有alternation 的单一模式:

    ((?<=[^\W[A-Z])[A-Z]|(?<=\S)[A-Z](?=[a-z]))
    

    在替换中使用一个空格,后跟第 1 组:

     \1
    

    说明

    • (抓拍群
      • (?&lt;= 正向前瞻,断言右边是
        • [^\W[A-Z]匹配除A-Z以外的单词字符
      • ) 关闭正向预测
      • |或者
      • (?&lt;=\S) 正向向后看,断言左边是
      • [A-Z]匹配A-Z
      • (?=[a-z])正向前瞻,断言右边是a-z
    • )关闭捕获组

    Regex demo | Python demo

    例如

    import re
    
    strings = [
        "General Manager or VP Torrance, CARequired education",
        "WordWordWord",
        "DaveIsAFKRightNow!Cool"
    ]
    pattern = re.compile(r'((?<=[^\W[A-Z])[A-Z]|(?<=\S)[A-Z](?=[a-z]))')
    
    for str in strings:
        print(pattern.sub(r' \1', str)) 
    

    结果

    General Manager or VP Torrance, CA Required education
    Word Word Word
    Dave Is AFK Right Now! Cool
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 2022-12-10
      • 2022-01-10
      相关资源
      最近更新 更多