JS RegExp - проверить на вхождение и вырезать последовательность цифр из строки

В общем нужно проверить вхождение последовательности из N цифр в строку. Если вхождение есть - вырезать и вернуть.

Проблемы начинаются если в строке есть символ переноса.

    const pattern = new RegExp("^(.*)([0-9]{6})(.*)$", "g");
    const messages = [
        `текст 123456 текст`,
        `123456 текст`,
        `текст 123456`,
        `123456`,

        `текст
        текст 123456 текст
        текст`, // на многострочном тексте не работает
    ];

    messages.forEach((message, index) => {
        if (pattern.test(message)) {
            console.log(index, message.replace(pattern, "$2"));
        } else {
            console.log(index, false);
        }
    });

Конечно же можно сделать что то типа такого:

    messages.forEach((message, index) => {
        if (pattern.test(message.replace("\n", ""))) {
            console.log(index, message.replace("\n", "").replace(pattern, "$2"));
        } else {
            console.log(index, false);
        }
    });

Но хочется уместить все в один паттерн


Ответы (1 шт):

Автор решения: Wiktor Stribiżew

Для того, чтобы шаблон . находил символы переноса строки, необходимо

  • В современных версиях JS (поддерживающих ECMAScript 2018) использовать флаг s, /.*(\d{6}).*/s
  • Заменить .* на [\s\S]*, [\w\W]*, [\d\D]* либо [^]*

Однако в данном случае, вы хотите найти одну/все последовательности и 6 цифр в строке, используйте /\d{6}/g с методом String#match():

const pattern = /\d{6}/g;
const messages = [
  `текст 123456 текст`,
  `123456 текст`,
  `текст 123456`,
  `123456`,

  `текст
        текст 123456 текст
        текст`, 
  `текст
        текст 123456 текст
        текст 678901`,  // Несколько вхождений
];

messages.forEach((message, index) => {
  const match = message.match(pattern)
  if (match) {
    console.log(index, match);
  } else {
    console.log(index, false);
  }
});

Если нужно найти только целые слова (т.е. исключить совпадение 123456 в строке 01234567) используйте

const pattern = /\b\d{6}\b/g; // Где \b — это границы слова
const pattern = /(?<!\d)\d{6}(?!\d)/g; // Где (?<!\d)/(?!\d) запрещают цифры с двух сторон совпадения
const pattern = /(?<!\S)\d{6}(?!\S)/g; // Только если с двух сторон пробельные символы или начало/конец строки
→ Ссылка