Ленивое совпадение Регулярное выражение узла по нескольким строкам - PullRequest
1 голос
/ 15 апреля 2020

Я пытаюсь разобрать кучу javascript файлов и вытащить определенные объекты. Пример файла будет:

import { foo } from "blah";
import { bar, baz } from "../module";

const myobject = {
    name: NAME,
    title: {
        name: `${NAME}.title`,
        defaultMessage: "title",
    },
    description: {
        name: `${NAME}.description`,
        defaultMessage: "description",
    },
    property: 'stringvalue',
};

const anotherObject = {
        name: `${NAME}.other`,
        defaultMessage: "other",
}

Мне нужно вытащить все объекты, которые имеют свойство "defaultMessage". Для сопоставителя у меня есть:

/\{([\s\S]*?)defaultMessage([\s\S]*?)\}/g

Это соответствует anotherObject и myobject.description правильно, но для myobject.title он получает все от первого { до foo. Например:

{ foo } from "blah";
import { bar, baz } from "../module";

const myobject = {
    name: NAME,
    title: {
        name: `${NAME}.title`,
        defaultMessage: "Main",
    }

Как я могу получить это для ленивого соответствия, так что я получаю только:

{
    name: `${NAME}.title`,
    defaultMessage: "Main",
}

Обновление: я буду использовать узел для разбора файлов javascript, так что я получил доступ к негативным взглядам за спиной, безуспешно пробовал следующее:

(?<!\{[\s\S]+?)\{([\s\S]+?)defaultMessage([\s\S]*?)\}

1 Ответ

0 голосов
/ 15 апреля 2020

Я бы не использовал это в каком-либо производственном коде, но это сработало бы для вашего случая:

([a-zA-Z]*?)(?:\s=|:)\s(\{(?:(?!([a-zA-Z]*?)(\s=|:)\s\{)[\s\S])*?defaultMessage(?:[\s\S]*?)\})

Я добавил ([a-zA-Z]*?)(\s=|:)\s, поэтому мы фиксируем открывающую скобку, только если она имеет префикс xyZ = или `ab C: '.

Также добавлен отрицательный прогноз, чтобы шаблон не повторялся:

(?!([a-zA-Z]*?)(\s=|:)\s\{)

Кроме того, я добавил несколько групп без захвата, чтобы уменьшите беспорядок в регулярных выражениях, если вы собираетесь использовать это в некотором коде. Например, это регулярное выражение захватывает:

    title: {
        name: `${NAME}.title`,
        defaultMessage: "title",
    } 

С title в качестве подгруппы 1

и:

{
        name: `${NAME}.title`,
        defaultMessage: "title",
}

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

В качестве альтернативы используйте:

(?=[a-zA-Z]*?)\{(?:(?!([a-zA-Z]*?)(\s=|:)\s\{)[\s\S])*?defaultMessage(?:[\s\S]*?)\}

Только для захвата:

{
        name: `${NAME}.title`,
        defaultMessage: "title",
}

Без подгрупп

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