Подтвердить что ты не робот

Python: конвертируйте случай с верблюдом в пространство, ограниченное с помощью RegEx, и принимая во внимание Акронимы

Я пытаюсь преобразовать случай верблюда в пробельные значения, используя python. Например:

divLineColor → div Цвет строки

Эта строка делает это успешно:

label = re.sub("([A-Z])"," \g<0>",label)

У меня проблема с такими вещами, как simpleBigURL, они должны это сделать:

simpleBigURL → простой большой URL

Я не совсем уверен, как получить этот результат. Помогите!


Это одна вещь, которую я пробовал:

label = re.sub("([a-z])([A-Z])","\g<0> \g<1>",label)

Но это приводит к таким странным результатам, как:

divLineColor → divL vineC eolor

Я также думал, что использование (?!...) может работать, но мне не повезло.

4b9b3361

Ответ 1

\g<0> ссылается на согласованную строку всего шаблона, в то время как \g<1> реферирует совпадающую строку первого подшаблона ((…)). Поэтому вместо \g<1> и \g<2> следует использовать

label = re.sub("([a-z])([A-Z])","\g<1> \g<2>",label)

Ответ 2

Это должно работать с 'divLineColor', 'simpleBigURL', 'OldHTMLFile' и 'SQLServer'.

label = re.sub(r'((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))', r' \1', label)

Пояснение:

label = re.sub(r"""
        (            # start the group
            # alternative 1
        (?<=[a-z])  # current position is preceded by a lower char
                    # (positive lookbehind: does not consume any char)
        [A-Z]       # an upper char
                    #
        |   # or
            # alternative 2
        (?<!\A)     # current position is not at the beginning of the string
                    # (negative lookbehind: does not consume any char)
        [A-Z]       # an upper char
        (?=[a-z])   # matches if next char is a lower char
                    # lookahead assertion: does not consume any char
        )           # end the group""",
    r' \1', label, flags=re.VERBOSE)

Если совпадение найдено, оно заменяется на ' \1', которое представляет собой строку, состоящую из ведущего пустого и самого совпадения.

Альтернатива 1 для совпадения - это верхний символ, но только если ему предшествует младший символ. Мы хотим перевести abYZ на ab YZ, а не на ab Y Z.

Альтернатива 2 для совпадения - это верхний символ, но только если за ним следует нижний символ, а не в начале строки. Мы хотим перевести ABCyz на AB Cyz, а не на A B Cyz.

Ответ 3

Я знаю, это не регулярное выражение. Но вы также можете использовать map, как это

>>> s = 'camelCaseTest'
>>> ''.join(map(lambda x: x if x.islower() else " "+x, s))
'camel Case Test'

Ответ 4

(?<=[a-z])([A-Z])
или
([a-z])([A-Z])

Ответ 5

Я не смог получить действительно приятное регулярное выражение, но это работало прилично.

([a-z]+)([A-Z][a-z]+)?([A-Z][a-z]+)?([A-Z][a-z]+)?([A-Z][a-z]+)?

Разбивая его, это:

([a-z]+) Любые серии строчных символов

([A-Z][a-z]+)? Любой символ верхнего регистра, за которым следуют 1 или более строчных символов. Это необязательно

Затем я повторил вторую группу 4 раза. Это будет работать, только если у вас не более 4 "разделов" или символов верхнего регистра. Добавьте или удалите эту группу регулярных выражений по мере необходимости. Он будет работать, если будет меньше этого числа (т.е. Будет работать на divLineColor). Это не будет соответствовать словам, которые являются прописными буквами.

Ответ 6

>>> def unCamel(x): return reduce(lambda a,b: a + ((b.upper() == b and (len(a) and a[-1].upper() != a[-1])) and (' ' + b) or b), x, '')
... 
>>> 
>>> unCamel("simpleBigURL")
'simple Big URL'
>>> unCamel("URL")
'URL'
>>> unCamel("url")
'url'
>>> unCamel("uRl")
'u Rl'

Ответ 7

Я не думаю, что вы можете сделать это, используя регулярное выражение, потому что вам нужно запомнить предыдущий элемент, чтобы сделать это для всех случаев. Я думаю, что для всех случаев работает следующая функция. Например, он преобразует "AbcdEfgHIJKlmno" в "Abcd Efg HIJ Klmno"

def camel_case_to_phrase(s):
  prev = None
  t = []
  n = len(s)
  i = 0

  while i < n:
    next_char = s[i+1] if i < n -1 else ''
    c = s[i]
    if prev is None:
        t.append(c)
    elif c.isupper() and prev.isupper():
        if next_char.islower():
            t.append(' ')
            t.append(c)
        else:
            t.append(c)
    elif c.isupper() and not prev.isupper():
        t.append(' ')
        t.append(c)
    else:
        t.append(c)
    prev = c
    i = i +1

return "".join(t)

Ответ 8

Здесь мое простое решение, которое работает с реализациями типа PCRE, включая Python:

/(?<=[a-zA-Z])(?=[A-Z])/g

Затем просто замените все совпадения на одно пространство (). Объединяя все это:

re.sub(r'(?<=[a-zA-Z])(?=[A-Z])', ' ', yourCamelCaseString);

SSCCE