Regex - найти пробелы в группе захвата

Мы используем некоторые структуры имен файлов, как пользователи должны сохранять файлы.

У меня есть огромный список всех наших файлов в Excel, и мне нужно проверить имена файлов.

В кратком пояснении имя файла начинается с номера детали. Номер детали содержит «группы», разделенные дефисом.

Основная проблема заключается в том, что пользователи иногда используют пробелы (случайно) с дефисами для разделения групп.

Я должен пометить имена файлов в списке так: - правильно - похоже, но неправильно - не совпадает

Аналогично означает, если порядок групп правильный, но разделение групп осуществляется не только дефисом (-), но и в сочетании с пробелами: ' - ' или '- ' или ' -' или '- ' и т. д..

Я написал макрос регулярного выражения в VBA. Это работает хорошо, но я придерживаюсь «похожего» шаблона.

Вот упрощенная версия одной структуры в регулярном выражении:

^(\d{4}-\d{2}(?:-\d{3})?-[A-Z]\d{3}-[A-Z])(?: - )(.*)

В этом случае интересной частью является первая группа захвата, номер детали. Как вы видите, в первой группе захвата есть группа без захвата, которая не является обязательной. Две группы захвата (номер детали и описание) разделены символом «-».

Примеры правильного имени файла:

1111-22-333-A444-B - DESCR.EXT

1111-22-A444-B - DESCR.EXT

Примеры для похожего, но неправильного имени файла:

1111-22 -333-A444-B - DESCR.EXT

1111-22- A444-B - DESCR.EXT

1111 -22-333-A444-B - DESCR.EXT

1111  -22 - A444-  B - DESCR.EXT

1111 - 22 -  A444 - B - DESCR.EXT

Примеры для несовпадающего имени файла:

1111-22-333-A444 - DESCR.EXT

1111-22-B - DESCR.EXT

1111-22-333-A444-BDESCR.EXT

1111-22 - DESCR.EXT

1111-22-33-444-B - DESCR.EXT

1111-22-444-B - DESCR.EXT

Я могу пометить правильные и несоответствующие значения с помощью шаблона выше, но я не знаю, как изменить, чтобы проверить, что «похоже»? Я пытался найти решение здесь и в Google, но не нашел :/

Спасибо


person norbre    schedule 21.01.2020    source источник
comment
Удалить пробел, прежде чем передать его регулярному выражению?   -  person JP Alioto    schedule 22.01.2020


Ответы (1)


Измените - и (?: - ) на \s*-\s*, чтобы принималось любое произвольное количество начальных и/или конечных пробелов, включая отсутствие пробелов (только дефис). (Я также удалил закрывающий (?:…), так как он не использовался.)

В этой интерактивной демонстрации у меня есть две версии вашего регулярного выражения. Один для достоверности (регулярное выражение в вопросе) и один для подобия, который более расслаблен в отношении интервалов с моим предложением выше. Действительные записи окрашены в зеленый цвет, похожие записи — в красный. Вы можете поиграть с регулярными выражениями и перезапустить их по мере необходимости.

function check(elem) {
  let next = elem.nextElementSibling;
  let okay = elem.innerHTML.match(document.getElementById("okay").value);
  let sim = elem.innerHTML.match(document.getElementById("sim").value);
  if (okay) {
    next.innerHTML = " → 1=[" + okay[1] + "] 2=[" + okay[2] + "]";
    next.className = "";
  } else if (sim) {
    next.innerHTML = " → 1=[" + sim[1] + "] 2=[" + sim[2] + "]";
    next.className = "similar";
  } else {
    next.innerHTML = "";
  }
}

function go() {
  document.querySelectorAll("li pre").forEach(item => check(item));
}
li { list-style:none; }
pre { display:inline-block; }
pre, ul, li { margin-top:0; margin-bottom:0 }
input[type="text"] { width:96%; font-family:monospace; }
input { display:block; }
pre + b { color:#080; font-family:monospace; }
pre + b.similar { color:#800; }
Valid: <input type="text" id="okay" 
  value="^(\d{4}-\d{2}(?:-\d{3})?-[A-Z]\d{3}-[A-Z]) - (.*)" />
Similar: <input type="text" id="sim" 
  value="^(\d{4}\s*-\s*\d{2}(?:\s*-\s*\d{3})?\s*-\s*[A-Z]\d{3}\s*-\s*[A-Z])\s*-\s*(.*)" />
<input type="button" value="go" onclick="go()" />

<b>Correct</b>
<ul id="correct">
<li><pre>1111-22-333-A444-B - DESCR.EXT</pre><b></b></li>
<li><pre>1111-22-A444-B - DESCR.EXT</pre><b></b></li>
</ul>

<b>Similar but wrong file name</b>
<ul id="similar">
<li><pre>1111-22 -333-A444-B - DESCR.EXT</pre><b></b></li>
<li><pre>1111-22- A444-B - DESCR.EXT</pre><b></b></li>
<li><pre>1111 -22-333-A444-B - DESCR.EXT</pre><b></b></li>
<li><pre>1111  -22 - A444-  B - DESCR.EXT</pre><b></b></li>
<li><pre>1111-22-333-A444-B - DESCR.EXT</pre><b></b></li>
<li><pre>1111 - 22 -  A444 - B - DESCR.EXT</pre><b></b></li>
</ul>

<b>Non-matching filename</b>
<ul id="non-matching">
<li><pre>1111-22-333-A444 - DESCR.EXT</pre><b></b></li>
<li><pre>1111-22-B - DESCR.EXT</pre><b></b></li>
<li><pre>1111-22-333-A444-BDESCR.EXT</pre><b></b></li>
<li><pre>1111-22 - DESCR.EXT</pre><b></b></li>
<li><pre>1111-22-33-444-B - DESCR.EXT</pre><b></b></li>
<li><pre>1111-22-444-B - DESCR.EXT</pre><b></b></li>
</ul>

Как видите, предпоследнее «похожее» имя файла соответствует исходному регулярному выражению. Я не уверен, что там было задумано.

person Adam Katz    schedule 21.01.2020
comment
предпоследнее подобное было моей ошибкой. Выглядит хорошо и просто, не знаю, почему я не подумал об этом :) Спасибо - person norbre; 22.01.2020