Именованные группы в регулярном выражении, преобразованные в новую конструкцию `RegExp` из строки - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь построить регулярное выражение из серии меньших регулярных выражений в виде строки или примитива.

Я использую Node v10.15.0.

Вот мои 3 компонента по отдельности

Соответствие месяца: /\b(?<month>\bjan(?:uary)?\b|\bfeb(?:ruary)?\b|\bmar(?:ch)?\b|\bapr(?:il)?\b|\bmay\b|\bjun(?:e)?\b|\bjul(?:y)?\b|\baug(?:ust)?\b|\bsep(?:tember)?\b|\boct(?:ober)?\b|\bnov(?:ember)?\b|\bdec(?:ember)?\b)/i

Соответствие дня: /(?<day>\d{1,2})/i

Соответствие года: /(?<year>20\d\d)/i

Я пытаюсь создать регулярное выражение изкаждый из которых будет выглядеть примерно так:

new RegExp(/\b(?<month>\bjan(?:uary)?\b|\bfeb(?:ruary)?\b|\bmar(?:ch)?\b|\bapr(?:il)?\b|\bmay\b|\bjun(?:e)?\b|\bjul(?:y)?\b|\baug(?:ust)?\b|\bsep(?:tember)?\b|\boct(?:ober)?\b|\bnov(?:ember)?\b|\bdec(?:ember)?\b) (?<day>\d{1,2}), (?<year>20\d\d)/i);

Это будет соответствовать «14 апреля 2018», «25 июня 2019» и т. д. и т. д.

Я сделал несколько попыток построения с помощью:

  • new RegExp(/my-pattern/i)
  • new RegExp('my-pattern' + 'my-other-pattern, 'i')
  • new RegExp(new RegExp('my-pattern', 'i') + new RegExp('other-pattern', 'i') (это кажется наиболее глупым).

Один странный эффект, который я заметил, был, когда я пытался построить строку.Кроме того, конструктор будет обрезать вывод - посмотрите, как именованная группа «месяц» изменяется ниже:

var z = new RegExp('\b(?<month>\bjan(?:uary)?\b|\bfeb(?:ruary)?\b|\bmar(?:ch)?\b|\bapr(?:il)?\b|\bmay\b|\bjun(?:e)?\b|\bjul(?:y)?\b|\baug(?:ust)?\b|\b
sep(?:tember)?\b|\boct(?:ober)?\b|\bnov(?:ember)?\b|\bdec(?:ember)?\b)' + '(?<day>\d{1,2})', 'i');
undefined

>>> (?<monthjan(?:uary)feb(?:ruary)mar(?:ch)apr(?:il)majun(?:e)jul(?:y)aug(?:ust)sep(?:tember)oct(?:ober)nov(?:ember)dec(?:ember))(?<day>d{1,2})/i

Кто-нибудь может посоветовать лучший подход для этого?В противном случае я, скорее всего, снова и снова буду объявлять совпадения месяцев / дней / лет очень подробными образцами.

Спасибо

1 Ответ

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

Это выражение может помочь вам сопоставить желаемые строки даты.

((1[0-2]|0?[1-9])\/(3[01]|[12][0-9]|0?[1-9])\/(?:[0-9]{2})?[0-9]{2})|(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\s+\d{1,2},\s+\d{4}

Вы можете упростить его и уменьшить границы, если хотите.

enter image description here

Описательный график RegEx

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

enter image description here

Тест JavaScript

const regex = /((1[0-2]|0?[1-9])\/(3[01]|[12][0-9]|0?[1-9])\/(?:[0-9]{2})?[0-9]{2})|(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\s+\d{1,2},\s+\d{4}/gm;
const str = `Apr 14, 2018`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Базовый тест производительности

Этот фрагмент JavaScript возвращает время выполнения цикла for в миллион раз для производительности.

const repeat = 1;
const start = Date.now();

for (var i = repeat; i >= 0; i--) {
	const string = 'Apr 14, 2018';
	const regex = /(((1[0-2]|0?[1-9])\/(3[01]|[12][0-9]|0?[1-9])\/(?:[0-9]{2})?[0-9]{2})|(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\s+\d{1,2},\s+\d{4})/gm;
	var match = string.replace(regex, "Group #1: $1");
}

const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ??? ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...