正则表达式分割大写字母

4 投票
5 回答
2595 浏览
提问于 2025-04-15 19:21

我想用正则表达式把像 'HDMWhoSomeThing' 这样的字符串替换成 'HDM Who Some Thing'

我的目标是提取那些以大写字母开头的单词,或者只由大写字母组成的单词。注意,在字符串 'HDMWho' 中,最后一个大写字母其实是单词 Who 的第一个字母,所以它不应该算在单词 HDM 里。

那么,怎样写正则表达式才能实现这个目标呢?我尝试了很多类似 [A-Z][a-z]+ 的正则表达式,但都没有成功。这个 [A-Z][a-z]+ 只给我找到了 'Who Some Thing',当然没有 'HDM'

有没有什么好的想法?谢谢,Rukki

5 个回答

2

一行代码:

' '.join(a or b for a,b in re.findall('([A-Z][a-z]+)|(?:([A-Z]*)(?=[A-Z]))',s))

使用正则表达式

([A-Z][a-z]+)|(?:([A-Z]*)(?=[A-Z]))

2

试着用这个正则表达式来进行分割:

/(?=[A-Z][a-z])/

如果你的正则表达式引擎不支持分割空匹配,可以试试这个正则表达式,它可以在单词之间加上空格:

/([A-Z])(?![A-Z])/

把它替换成 " $1"(空格加上第一个组匹配的内容)。这样你就可以在空格处进行分割了。

2
#! /usr/bin/env python

import re
from collections import deque

pattern = r'([A-Z]{2,}(?=[A-Z]|$)|[A-Z](?=[a-z]|$))'
chunks = deque(re.split(pattern, 'HDMWhoSomeMONKEYThingXYZ'))

result = []
while len(chunks):
  buf = chunks.popleft()
  if len(buf) == 0:
    continue
  if re.match(r'^[A-Z]$', buf) and len(chunks):
    buf += chunks.popleft()
  result.append(buf)

print ' '.join(result)

输出结果:

HDM Who Some MONKEY Thing XYZ

从代码行数来看,这个任务更适合用 re.findall 来完成:

pattern = r'([A-Z]{2,}(?=[A-Z]|$)|[A-Z][a-z]*)'
print ' '.join(re.findall(pattern, 'HDMWhoSomeMONKEYThingX'))

输出结果:

HDM Who Some MONKEY Thing X

撰写回答