Обходной путь из-за отсутствия поиска для регулярных выражений Javascript

1

У меня есть работающее выражение Regex для Python:

regex = re.compile(r"(?<=(==))(.*)(?=(==))")    
myList = regex.findall(contents)

Для контекста входная строка может напоминать (например):

== Test User ==
Comment here

== Test User 2 ==
Comment here

И я хочу извлечь имя пользователя и соответствующий комментарий в строке ниже.

Я хочу использовать это регулярное выражение в моей Javascript-программе, однако Javascript не имеет функции внешнего вида.

Есть ли подходящее решение для этого?

  • 0
    Разве решение Python не дает кортеж ('==', 'some value', '==') ? Вам нужно повторить это?
  • 0
    Вы абсолютно правы @ WiktorStribiżew, но мне не нужно повторять это точное поведение, просто я могу определить имя пользователя и комментарий.
Показать ещё 1 комментарий
Теги:
python-3.x

2 ответа

1

Стандартный способ - сопоставить как lookbehind, так и нужные данные и использовать группы захвата, чтобы делать то, что вы хотите:

  • если нужно извлечь данные, затем поместите их в группу захвата, которую вы проконсультируете после каждого матча

  • если нужно преобразовать данные, вы захотите иметь по крайней мере "lookbehind" в группе захвата, чтобы вы могли воспроизвести ее на выходе и, возможно, нужные данные, если вам нужно сослаться на нее.

Примеры:

# in these examples, we look for "overflow" preceded by "stack"
"stackoverflow".match(/stack(.*)/)[1]                // -> overflow
"stackoverflow".replace(/(stack).*/, "$1underflow")  // -> stackunderflow
"stackoverflow".replace(/(stack)(.*)/,"$2ed $1")     // -> overflowed stack

Другая проблема, с которой мы сталкиваемся с реализацией JavaScript regex, заключается в том, что поведение String.prototype.match несовместимо: оно, как правило, возвращает объект, родственный массиву захваченных групп, однако если ваше регулярное выражение задает флаг g lobal, оно вместо этого вернет массив (строка), и детали групп захвата будут потеряны.

Чтобы обойти это, вы можете использовать метод Pattern.prototype.exec:

var pattern = /==\s*([^=]+)/g;
var input = '== Test User ==
Comment here

== Test User 2 ==
Comment here';
while (match = pattern.exec(input)) {
    console.log(match[1]);
}
0

Вам здесь не нужно ничего искать, даже в Python вы можете избавиться от него и использовать следующее выражение с re.findall (просто удалите / и /gm и скомпилируйте флаг re.M):

/^==\s*(.*?)\s*==\s*(.*(?:\r?\n(?!\r?\n).*)*)/gm

См. Демо-версию regex.

Детали:

  • ^ - начало строки
  • ==\s* - two = символы, а затем 0+ пробелы
  • (.*?) - Группа 1, фиксирующая любые символы 0+, отличные от символов разрыва строки, как можно меньше до первого появления последующих подшаблонов
  • \s*==\s* - two = заключено с пробелами 0+
  • (.*(?:\r?\n(?!\r?\n).*)*) - захват группы 2
    • .* - остальная часть линии
    • (?:\r?\n(?!\r?\n).*)* - нулевая или более последовательность
      • \r?\n(?!\r?\n) - CRLF или LF (разрыв строки), не сопровождаемый LF или CRLF (другой разрыв строки)
      • .* - любые символы 0+, кроме символов прерывания строки (целая строка).

JS demo:

var s = '== Test User ==
Comment here, one line only

== Test User 2 ==
Comment here
with line 2';
var rx = /^==\s*(.*?)\s*==\s*(.*(?:\r?\n(?!\r?\n).*)*)/gm;
var results = [], m;
while(m=rx.exec(s)) {
  console.log("--- New match found ---");
  console.log("User:", m[1]);
  console.log("Comment:", m[2]);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню