У меня есть требование найти и вернуть первое вхождение шаблона из строки.
Пример: привет, мой SNO 05FK3NEK900058V, пожалуйста, добавь его
ожидаемый результат: 05FK3NEK900058V
Условие совпадения шаблона
Могу ли я сделать это с помощью регулярного выражения или мне нужно зацикливать слова?
Что я пробовал, но это не сработало
const regex = /\b^(?!\d*$|[a-zA-Z]*$)[a-zA-Z\d]{12,16}$\b/gm;
const str = `hello my SNO is 05FK3NEK900058V please add it `;
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.info(`Found match, group ${groupIndex}: ${match}`);
});
}
Вы можете использовать одно регулярное выражение, например
/\b(?=[a-zA-Z\d]{12,16}\b)(?:[a-zA-Z]*\d|\d*[a-zA-Z])[a-zA-Z\d]*\b/
См. демонстрация регулярных выражений.
Подробности
\b
- граница слова(?=[a-zA-Z\d]{12,16}\b)
- до границы следующего слова должно быть от 12 до 16 буквенно-цифровых символов(?:[a-zA-Z]*\d|\d*[a-zA-Z])
- либо 0+ букв и цифра, либо 0+ цифр и затем буква[a-zA-Z\d]*
- 0+ буквенно-цифровых символов\b
- граница слова.См. демонстрацию JS ниже:
var str = "hello my SNO is 05FK3NEK900058V please add it ";
var reg = /\b(?=[a-zA-Z\d]{12,16}\b)(?:[a-zA-Z]*\d|\d*[a-zA-Z])[a-zA-Z\d]*\b/;
var m = str.match(reg) || [""];
console.info(m[0]);
После комментария @bobble buble
Я думаю, это сработает:
\w{12,16}
Также вы можете использовать границы слов, если вы соответствуете требуемому слову.
\b\w{12,16}\b
Обновлено после комментария @PeterM:
Последняя версия более подробная, но более точная:
string=`Johannsonoff 111111111111111 05FK3NEK900058Vf 05FK3NEK900058Vfaf48 hello my SNO is fFK3NEK9000515 05FK3NEK9000515 please add it 05FK3NEK900058Vfaf48 faf fasf1654 EK90058Vs11 EK9005f8Vs12 05FK3NE90058Vs16 05FK3NEK90058Vs17`;
// Returns an Array in which elements are strings between 12 and 16 characters.
const groupMathed = string.match(/\b\w{12,16}\b/g)
// Returns the first element that have a digit [0-9] follow by a alphabetic character or a alphabetic character followed by a digit.
const alphanumericWord = groupMathed.find(e => /[0-9]+[a-zA-z]+|[a-zA-z]+[0-9]+/.test(e))
console.info(alphanumericWord)
Другой подход может использовать это регулярное выражение, которое является более подробным, но уменьшает код:
(?=(\b\d+[a-zA-Z]|\b[a-zA-Z]\d+))[a-zA-Z0-9]{12,16}\b
Демо: https://regex101.com/r/0lMyoV/11/
string=`asdfghjlqerut hello my SNO is 1234567891234 05FK3NEK900058V 0FK3NEK900058V asdfasfd25fasfaa please add it 05FK3NEK900058Vfaf48 faf fasf1654 F0K3NEK900058V Johannsonoff 111111111111111 05FK3NEK900058Vf 05FK3NEK900058Vfaf48 hello my SNO is fFK3NEK9000515 05FK3NEK9000515 please add it 05FK3NEK900058Vfaf48 faf fasf1654 EK90058Vs11 EK9005f8Vs12 05FK3NE90058Vs16 05FK3NEK90058Vs17 05FK3NEK900058Vfaf48`;
const regex = /(?=(\b\d+[a-zA-Z]|\b[a-zA-Z]\d+))[a-zA-Z0-9]{12,16}\b/g
const groupMathed = string.match(regex)
console.info(groupMathed)
Ты был прав @PeterM. Я обновил свой ответ. Спасибо за обнаружение проблемы.
@Pablo Спасибо за ваш ответ, небольшая проблема заключается в том, что совпадающие числа соответствуют только строке, т.е. строке = '111111111111111' вместо буквенно-цифровой.
@Dibish Я обновил код в «Последняя версия более подробная, но более точная:», чтобы решить эту проблему. Спасибо за обнаружение и сообщение о проблеме.
Ты прав @bobble buble! Буду тестить и обновлять!
let str = "hello (plus SomeLongWord) my SNO is 05FK3NEK900058V please add it ";
const reg = /\b[\w\d]{12,16}\b/g;
let m = str.match(reg);
if (typeof m === "object" && m.length) {
for (var indexM = 0; indexM < m.length; indexM++) {
// You can add more checks to filter long words
console.info(m[indexM]);
}
} else {
console.info("Not found any SNO here");
}
// results:
// SomeLongWord
// 05FK3NEK900058V
Это поможет вам обрабатывать длинные слова, но, вероятно, потребуется дополнительная проверка.
Это нормально, но также будут соответствовать длинные имена, например: привет, меня зовут Йохансонофф, мой SNO 05FK3NEK900058V, пожалуйста, добавь его