Преобразование Javascript RegEx.exec, который возвращает групповые совпадения в Python - PullRequest
0 голосов
/ 22 марта 2019

У меня есть этот типичный код в Javascript:

    NameRegEx = /\w+ \w+ (".*?"|\S+) (".*?"|\S+)/;
    term = NameRegEx.exec("add cmd item configname AAA 10.0.0.1 80 -option NONE -option2 YES -Option3 180");

Это работает, и «термин» является массивом, который содержит:

0: "add cmd item configname"
1: "item"
2: "configname"

Я не смог найтиэквивалентна функции exec в Python, и был бы признателен за некоторую помощь!У меня есть ряд похожих команд RegEx, которые мне также нужно преобразовать, поэтому мне нужна близкая альтернатива Python.

РЕДАКТИРОВАТЬ: это НЕ то же самое, что связанные дубликаты, поскольку они не учитывают факт того, как значениявернулись были разные.Однако Пушпеш Кумар Раджванши решил эту проблему с помощью приведенной ниже модификации регулярного выражения и приведенного ниже объяснения:

s = 'add cmd item configname AAA 10.0.0.1 80 -option NONE -option2 YES -Option3 180'
arr = [s for s in re.findall(r'(\w+ \w+ (".*?"|\S+) (".*?"|\S+))',s)[0]]
print(arr)

Да, эта дополнительная скобка была необходима, потому что вы хотели, чтобы в результатах массива была также захвачена полная строка.В противном случае findall просто включает результаты для ТОЛЬКО групп, а в случае, если группы нет, то и весь матч.

Открыт заново, поскольку вопросы, связанные как дубликаты, не полностью решают проблему.

1 Ответ

1 голос
/ 23 марта 2019

Во-первых, спасибо всем, кто согласился с тем, что этот пост должен быть открыт повторно, поскольку связанные посты не помогли ОП в том, что он искал.

И пока я отвечал, моим основным намерением было сохранить решение.близок к exec вызову функции в JS (а не к производительности, которая, конечно, была бы лучше для search, чем findall, так как последний выполняет больше работы, чем необходимо, но использует только первый элемент в массиве), и как exec функция в JS возвращает массив результатов, аналогичная функция в Python, которая возвращает результаты, например, массив был findall.

Так же, как в регулярном выражении OP /\w+ \w+ (".*?"|\S+) (".*?"|\S+)/ в JS не было глобального флага ON, что означаетон интересовался только первым совпадением, я использовал первый элемент [0] из findall результат, где мое решение кода Python было таким,

import re
s = 'add cmd item configname AAA 10.0.0.1 80 -option NONE -option2 YES -Option3 180'
arr = [s for s in re.findall(r'(\w+ \w+ (".*?"|\S+) (".*?"|\S+))', s)[0]]
print(arr)

Который напечатал,

['add cmd item configname', 'item', 'configname']

Но того же можно достичь и с помощью функции search, поскольку она выполняет многократный поиск один за другим, следовательно, она будет лучше, чем findall, поскольку findall находит все возможныевыполняется в результате сканирования всей строки за одну операцию, в отличие от search, но используется только первым путем доступа к первому элементу в массиве.Следовательно, публикация решения с использованием функции search, слишком похожей на findall, которая также может использоваться OP и будет работать лучше, так как это будет искать только первое совпадение.Поскольку groups() возвращает кортеж, но OP требуется массив, следовательно, этот код необходим, чтобы OP мог получать результаты в массиве точно так, как он хотел, как было возвращено методом exec в JS.

import re
s = 'add cmd item configname AAA 10.0.0.1 80 -option NONE -option2 YES -Option3 180'
m = re.search(r'(\w+ \w+ (".*?"|\S+) (".*?"|\S+))', s)
if (m):
 arr = [s for s in m.groups()]
 print(arr)

Печать,

['add cmd item configname', 'item', 'configname']

Но да, необходимо было одно изменение в регулярном выражении от JS, которое заключает все регулярное выражение в дополнительные скобки, без которых оно не дало бы результатов, которые ищет OP.

На самом деле вы можете создать функцию exec в Python, чтобы имитировать ее из JS примерно так:

import re

def exec(regex, s):
 m = re.search(regex, s)
 if (m):
  return [s for s in m.groups()]


arr = exec(r'(\w+ \w+ (".*?"|\S+) (".*?"|\S+))', 'add cmd item configname AAA 10.0.0.1 80 -option NONE -option2 YES -Option3 180')
print(arr)

, которая также дает тот же вывод и может использоваться многократно, следовательно, хороший способ делать вещи,

['add cmd item configname', 'item', 'configname']

Наконец, я рад, что в ходе здоровой дискуссии с помощью комментариев OP может найти рабочее решение проблемы.

Если у вас возникнут какие-либо проблемы или у вас возникнут вопросы, пожалуйста, не стесняйтесья знаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...