RegEx для соответствия слова после определенного слова в нескольких строках - PullRequest
3 голосов
/ 08 мая 2019

В некоторых редакторах, таких как VS Code, есть функция регулярного выражения для поиска слов вместо "Ctrl + F", я пытаюсь найти слово после определенного слова с некоторыми другими строками.

Например, как использовать регулярное выражение для фильтрации тех «someFunction» с определенным свойством «message», как показано ниже:

...
someFunction({
  a: true,
  b: false
})
someFunction({
  a: true,
  b: false,
  c: false,
  d: true,
  message: 'I wnat to find the funciton with this property'
})
someFunction({
  a: true
})
...

Используемое регулярное выражение выглядит так:

/someFunction[.*\s*]*message/

Но это не сработало

Как мне достичь этой цели?

Ответы [ 3 ]

3 голосов
/ 08 мая 2019

Ваше выражение просто отлично, вы можете немного изменить его следующим образом:

 someFunction[\S\s*]*message

Если вы также хотите получить свойство, это выражение может работать:

(someFunction[\S\s*]*message)(.*)

Вы можете добавить дополнительные границы, если хотите, возможно, используя regex101.com .

enter image description here

График

Этот график показывает, как будет работать ваше выражение, и вы можете визуализировать другие выражения в jex.im :

enter image description here

Тест производительности

Этот скрипт возвращает время выполнения строки для выражения.

repeat = 1000000;
start = Date.now();

for (var i = repeat; i >= 0; i--) {
	var string = "some other text someFunction \n            \n message: 'I wnat to find the funciton with this property'";
	var regex = /(.*)(someFunction[\S\s*]*message)(.*)/g;
	var match = string.replace(regex, "$3");
}

end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ??? ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");

const regex = /(someFunction[\S\s*]*message)(.*)/;
const str = `...
someFunction({
  a: true,
  b: false
})
someFunction({
  a: true,
  b: false,
  c: false,
  d: true,
  message: 'I wnat to find the funciton with this property'
})
someFunction({
  a: true
})
...`;
let m;

if ((m = regex.exec(str)) !== null) {
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}
1 голос
/ 08 мая 2019

В вашем шаблоне someFunction[.*\s*]*message вы можете использовать класс символов , который будет соответствовать только одному из нескольких символов и может быть записан как [.*\s]

Использование шаблона, подобного [\S\s]*, не будет учитывать любые другие функции с таким же именем или закрывающие границы, как }), и будет более соответствовать ему.

Если pcre2 не включен, на этой странице объясняется, как включить его, вы используете опережение.

Если вы хотите более точное совпадение, вы можете использовать:

^someFunction\(\{(?:\n(?!(?: +message:|}\))).*)*\n +message:(.*)\n}\)$

Объяснение

  • ^ Начало строки
  • someFunction\(\{ Совпадение someFunction({
  • (?: Группа без захвата
    • \n Соответствие новой строки
    • (?! Отрицательный взгляд
      • (?: Группа без захвата
        • +message: Соответствует 1+ пробелам, за которыми следует сообщение:
        • | или
        • }\) Совпадение })
      • ) Закрыть группу без захвата
    • ) Закрыть негативный взгляд
    • .* Соответствует любому символу, кроме новой строки
  • )* Закрыть группу захвата и повторить 0+ раз
  • \n +message: Совпадение с новой строкой и сообщением:
  • (.*)\n Захват в группе 1, соответствующий любому символу, кроме новой строки, за которой следует новая строка
  • }\) Матч })
  • $ Конец строки

Regex demo

0 голосов
/ 08 мая 2019

VSCode использует RipGrep , который использует Rust regex .

Следующий шаблон будет соответствовать 'message'

Чтобы выбрать до конца строки,

(?<=someFunction.*(\n.+)+)message.*$

для выбора только ключа, пропустите. * $

(?<=someFunction.*(\n.+)+)message
...