一种在大写字母前插入空格但不在缩写之间插入空格的pythonic方法

时间:2019-05-28 13:02:56

标签: regex python-3.x

我有一个文件,我正在通过python脚本更改其格式。我在此文件中有几个驼峰式的字符串,我只想在大写字母前插入一个空格-因此“ WordWordWord”变为“ Word Word Word”,但我也有一些缩写,例如文本“ General Manager or VP”。

我在这篇文章中找到了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

2 个答案:

答案 0 :(得分:0)

或者,您可以将单个模式与alternation一起使用:

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

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

 \1

说明

  • (捕获组
    • (?<=正向前进,断言右边是
      • [^\W[A-Z]匹配A-Z以外的文字字符
    • )积极回望
    • |
    • (?<=\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

答案 1 :(得分:0)

您可以将替换项交换为:首先在大写字母之前插入空格(除大写字母和空格以外的其他字符),然后在以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<0>将整个匹配项插入替换模式。