#python
#python
Вопрос:
У меня есть регулярное выражение, в котором я пытаюсь извлечь каждую группу букв, за которой не следует символ «(«. Например, следующее регулярное выражение работает с математической формулой, которая включает имена переменных (x, y и z) и имена функций (movav и movsum), оба из которых полностью состоят из букв, но где только имена функций сопровождаются «(«.
re.findall("[a-zA-Z] (?!()", "movav(x/2, 2)*movsum(y, 3)*z")
Я бы хотел, чтобы выражение возвращало массив
['x', 'y', 'z']
но вместо этого он возвращает массив
['mova', 'x', 'movsu', 'y', 'z']
Теоретически я понимаю, почему регулярное выражение будет возвращать второй результат, но есть ли способ изменить его, чтобы вернуть только массив ['x', 'y', 'z']
?
Ответ №1:
Другое решение, которое не зависит от границ слов:
Убедитесь, что за буквами не следует ни a (
, ни другая буква.
>>> re.findall(r'[a-zA-Z] (?![a-zA-Z(])', "movav(x/2, 2)*movsum(y, 3)*z")
['x', 'y', 'z']
Комментарии:
1. Этот ответ, вероятно, лучший, потому что он хорошо подходит для ситуации, когда символы в переменной расширяются, чтобы разрешить странные символы, такие как «$» или «@».
Ответ №2:
Добавьте средство сопоставления границ слов b
:
>>> re.findall(r'[a-zA-Z] b(?!()', "movav(x/2, 2)*movsum(y, 3)*z")
['x', 'y', 'z']
b
соответствует пустой строке между двумя словами, так что теперь вы ищете буквы, за которыми следует граница слова, за которой сразу не следует (
. Для получения более подробной информации см. re
Документы.
Комментарии:
1. Спасибо Дугалу и эхуморо за ваши решения.
Ответ №3:
Вам нужно ограничить совпадения целыми словами. Поэтому используйте b
для сопоставления начала или конца слова:
re.findall(r"b[a-zA-Z] b(?!()", "movav(x/2, 2)*movsum(y, 3)*z")
Ответ №4:
Альтернативный подход: найдите строки букв, за которыми следует либо конец строки, либо символ, не состоящий из букв, не заключенный в скобки; затем захватите часть буквы.
re.findall("([a-zA-Z] )(?:[^a-zA-Z(]|$)", "movav(x/2, 2)*movsum(y, 3)*z")