Регулярное выражение делится на верхний регистр - PullRequest
4 голосов
/ 16 февраля 2010

Я хотел бы заменить строки типа 'HDMWhoSomeThing' на 'HDM Who Some Thing' на регулярное выражение.

Так что я хотел бы извлечь слова, которые начинаются с заглавной буквы или состоят только из заглавных букв. Обратите внимание, что в строке 'HDMWho' последняя заглавная буква фактически является первой буквой слова Who и не должна включаться в слово HDM.

Какое правильное регулярное выражение для достижения этой цели? Я пробовал много регулярных выражений, похожих на [A-Z][a-z]+, но безуспешно. [A-Z][a-z]+ дает мне 'Who Some Thing' - без 'HDM' конечно.

Есть идеи? Спасибо, Rukki

Ответы [ 5 ]

2 голосов
/ 16 февраля 2010
#! /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
2 голосов
/ 16 февраля 2010

один вкладыш:

'' .join (a или b для a, b в re.findall ('([AZ] [az] +) | (?: ([AZ] *) (? = [AZ]))', s))

с использованием регулярного выражения

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

2 голосов
/ 16 февраля 2010

Попробуйте разделить это регулярное выражение:

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

И если ваш механизм регулярных выражений не поддерживает разбиение пустых совпадений, попробуйте это регулярное выражение, чтобы поставить пробелы между словами:

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

Замените его на " $1" (пробел плюс совпадение первой группы). Тогда вы можете разделить в пространстве.

1 голос
/ 16 февраля 2010

Итак, «слова» в этом случае:

  1. Любое количество заглавных букв - если только за последней заглавной буквой не следует строчная буква.
  2. Одна заглавная буква, за которой следует любое количество строчных букв.

так что попробуйте:

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

Первое чередование включает в себя отрицательный прогноз (?! [A-z]), который обрабатывает границу между словом «все заглавные буквы» и словом начальных заглавных букв.

1 голос
/ 16 февраля 2010

Может быть '[A-Z] *? [A-Z] [a-z] +'?

Редактировать: Это похоже на работу: [A-Z] {2,} (?! [A-z]) | [A-Z] [a-z] +

import re

def find_stuff(str):
  p = re.compile(r'[A-Z]{2,}(?![a-z])|[A-Z][a-z]+')
  m = p.findall(str)
  result = ''
  for x in m:
    result += x + ' '
  print result

find_stuff('HDMWhoSomeThing')
find_stuff('SomeHDMWhoThing')

Распечатывает:

HDM Who Someing

Какой-то HDM Who Thing

...