Попытка отфильтровать строку для нескольких значений с помощью регулярного выражения

#javascript #regex

#javascript #регулярное выражение

Вопрос:

Мне нужно сопоставить кратные группы из кратных строк в соответствии со структурированной исходной строкой.

Строка форматируется с одним именем в строке, но с некоторыми другими значениями, в этом порядке:

  • Перед именем, начинающим каждую строку, может быть число;
  • Могут быть некоторые ненужные разделители между номером и именем;
  • Имя может содержать любой символ, включая символы в виде круглых скобок, апостроф и т. Д;
  • Может содержать код в круглых скобках с 3 или 4 буквами после имени (не беспокойтесь о том, что имя может содержать 3 или 4 буквы в круглых скобках, этого не произойдет)
  • Может иметь звездочку в конце строки, перед линией разрыва.

Мне нужно получить эти 4 группы для каждой строки. Это то, что я пытаюсь :

 /^(d )?(?:[ t]?[x:.=]?)[ t]?(. ?)(?=[ t]?((w{3,4}))?[ t]?(*))$/igm
 

Чтобы перехватить число:

 ^(d )?
 

Для очистки возможных разделителей:

 (?:[ t]?[x:.=]?)
 

Фильтрация пространства между каждой группой:

 [ t]?
 

Имя (и все остальное):

 (. ?(?=[ t]?((w{3,4}))?[ t]?(*)?))
 

Проблема, очевидно, в этом последнем. Он собирает все вместе (группы 2, 3 и 4). Как вы можете видеть, я использую две последние необязательные группы в качестве положительных ориентиров, чтобы отделить их от имени.

Что я делаю не так или как было бы лучше достичь результата?

Редактировать

Образец строки:

 2 John Smith
3 Messala Oliveira (NMN) *
Mary Pop *
Joshua Junior (pMHH)
 

Что мне нужно:

 [ "2", "John Smith", "", "" ],
[ "3", "Messala Oliveira", "(NMN)", "*" ],
[ "", "Mary Pop", "", "*" ],
[ "", "Joshua Junior", "(pMHH)", "" ],
 

Комментарии:

1. Пожалуйста, предоставьте примеры строк, которые вы хотите пройти тест

2. ...([^ t].*?)[ t]?((w{3,4})?[ t]?(*)? ?

3. @melpomene, спасибо. Раньше я пробовал без предварительного просмотра, но, думаю, я писал что-то не так. Теперь это работает так, как задумано. Спасибо!

Ответ №1:

Вам нужно обернуть группы захвата, которые могут присутствовать или отсутствовать, необязательными группами без захвата:

 /^(?:(d )[ t]*)?(.*?)(?:[ t]((w{3,4})))?(?:[ t](*))?$/igm
 

Смотрите демонстрацию регулярных выражений.

Подробные сведения:

  • ^ — начало строки
  • (?:(d )[ t]*)? — необязательное сопоставление групп без захвата
    • (d ) — (Группа 1) 1 цифры
    • [ t]* — 0 пробелов или табуляции (если s используется, 0 пробелов)
  • (.*?) — Группа 2 захватывает любые символы 0 , отличные от символов linenbreaks, как можно меньше
  • (?:[ t]((w{3,4})))? — необязательное сопоставление групп
    • [ t] — пробел или табуляция
    • ((w{3,4})) — Группа 3 захватывает символы a ( , 3 или 4 слова, )
  • (?:[ t](*))? — еще одна необязательная группа, соответствующая пробелу или табуляции и записывающая в группу 4 * символ.
  • $ — конец строки.

Если вы проверяете строки отдельно, [ t] их можно заменить более простым s :

 var regex = /^(?:(d )s*)?(.*?)(?:s((w{3,4})))?(?:s(*))?$/i;
var strs = ['2 John Smith','3 Messala Oliveira (NMN) *','Mary Pop *','Joshua Junior (pMHH)'];

for (var i=0; i<strs.length; i  ) {
    if ((m = regex.exec(strs[i])) !== null) {
        var res = [];
        if (m[1]) { 
          res.push(m[1]); 
        } else res.push("");
        res.push(m[2]);
        if (m[3]) { 
          res.push(m[3]); 
        } else res.push("");
        if (m[4]) { 
          res.push(m[4]); 
        } else res.push("");
    }
    console.log(res);
}