Відповіді:
Ось як створити регулярний вираз без використання буквеного синтаксису регулярного виразу. Це дозволяє робити довільну обробку рядків, перш ніж вона стане об'єктом регулярного вираження:
var segment_part = "some bit of the regexp";
var pattern = new RegExp("some regex segment" + /*comment here */
segment_part + /* that was defined just now */
"another segment");
Якщо у вас є два літерали регулярного вираження, ви можете насправді об'єднати їх за допомогою цієї методики:
var regex1 = /foo/g;
var regex2 = /bar/y;
var flags = (regex1.flags + regex2.flags).split("").sort().join("").replace(/(.)(?=.*\1)/g, "");
var regex3 = new RegExp(expression_one.source + expression_two.source, flags);
// regex3 is now /foobar/gy
Це просто багатослівніше, ніж просто вираз один і два є буквальними рядками замість буквальних регулярних виразів.
new RegExp(/(/.source + /.*/.source + /)?/.source);
, здається, не працює.
expression_one
? Ви маєте на увазі regex1
?
Просто випадкові об'єднання об'єктів регулярних виразів можуть мати деякі несприятливі побічні ефекти. Використовуйте натомість RegExp.source :
var r1 = /abc/g;
var r2 = /def/;
var r3 = new RegExp(r1.source + r2.source,
(r1.global ? 'g' : '')
+ (r1.ignoreCase ? 'i' : '') +
(r1.multiline ? 'm' : ''));
console.log(r3);
var m = 'test that abcdef and abcdef has a match?'.match(r3);
console.log(m);
// m should contain 2 matches
Це також дасть вам можливість зберігати прапори регулярних виразів з попереднього RegExp, використовуючи стандартні прапорці RegExp.
RegExp.prototype.flags
Я не зовсім згоден з варіантом "eval".
var xxx = /abcd/;
var yyy = /efgh/;
var zzz = new RegExp(eval(xxx)+eval(yyy));
дасть "// abcd // efgh //", що не є наміченим результатом.
Використання подібного джерела
var zzz = new RegExp(xxx.source+yyy.source);
дасть "/ abcdefgh /", і це правильно.
Логічно немає необхідності оцінювати, ви знаєте своє ВИРАЗ. Вам просто потрібен його ДЖЕРЕЛ або те, як це написано не обов'язково його значення. Що стосується прапорів, то вам просто потрібно використовувати необов'язковий аргумент RegExp.
У моїй ситуації я бігаю у випуску ^ і $, використовуваних у кількох виразах, які я намагаюся об'єднати разом! Ці вирази - це граматичні фільтри, які використовуються в програмі. Тепер я не хочу використовувати деякі з них разом для розгляду справи ПРЕПОЗИЦІЙ. Можливо, мені доведеться "нарізати" джерела, щоб видалити початковий і кінцевий ^ (та / або) $ :) Привіт, Олексій.
var regex = "\.\..*"
Проблема Якщо регулярний вираз містить групи, що відповідають типі, як \ 1.
var r = /(a|b)\1/ // Matches aa, bb but nothing else.
var p = /(c|d)\1/ // Matches cc, dd but nothing else.
Тоді просто контактувати з джерелами не вийде. Дійсно, поєднання двох таких:
var rp = /(a|b)\1(c|d)\1/
rp.test("aadd") // Returns false
Рішення: Спочатку ми підраховуємо кількість груп, що співпадають у першому регексе, Потім для кожного маркерів, що співпадають у другому, збільшуємо його на кількість груп, що відповідають.
function concatenate(r1, r2) {
var count = function(r, str) {
return str.match(r).length;
}
var numberGroups = /([^\\]|^)(?=\((?!\?:))/g; // Home-made regexp to count groups.
var offset = count(numberGroups, r1.source);
var escapedMatch = /[\\](?:(\d+)|.)/g; // Home-made regexp for escaped literals, greedy on numbers.
var r2newSource = r2.source.replace(escapedMatch, function(match, number) { return number?"\\"+(number-0+offset):match; });
return new RegExp(r1.source+r2newSource,
(r1.global ? 'g' : '')
+ (r1.ignoreCase ? 'i' : '')
+ (r1.multiline ? 'm' : ''));
}
Тест:
var rp = concatenate(r, p) // returns /(a|b)\1(c|d)\2/
rp.test("aadd") // Returns true
function concatenateList() { var res = arguments[0]; for(var i = 1; i < arguments.length; i++) { res = concatenate(res, arguments[i]); } return res; }
Краще використовувати буквальний синтаксис якомога частіше. Він коротший, більш розбірливий, і вам не потрібні котирування втечі чи подвійні люки. З "Шаблони Javascript", Стоян Стефанов, 2010.
Але використання Нового може бути єдиним способом об'єднання.
Я б уникнув овалів. Це не безпечно.
Надаючи це:
/this/g
а не new RegExp('this', 'g')
;Тоді ви можете написати так:
var regexParts =
[
/\b(\d+|null)\b/,// Some comments.
/\b(true|false)\b/,
/\b(new|getElementsBy(?:Tag|Class|)Name|arguments|getElementById|if|else|do|null|return|case|default|function|typeof|undefined|instanceof|this|document|window|while|for|switch|in|break|continue|length|var|(?:clear|set)(?:Timeout|Interval))(?=\W)/,
/(\$|jQuery)/,
/many more patterns/
],
regexString = regexParts.map(function(x){return x.source}).join('|'),
regexPattern = new RegExp(regexString, 'g');
ви можете зробити щось на кшталт:
string.replace(regexPattern, function()
{
var m = arguments,
Class = '';
switch(true)
{
// Numbers and 'null'.
case (Boolean)(m[1]):
m = m[1];
Class = 'number';
break;
// True or False.
case (Boolean)(m[2]):
m = m[2];
Class = 'bool';
break;
// True or False.
case (Boolean)(m[3]):
m = m[3];
Class = 'keyword';
break;
// $ or 'jQuery'.
case (Boolean)(m[4]):
m = m[4];
Class = 'dollar';
break;
// More cases...
}
return '<span class="' + Class + '">' + m + '</span>';
})
У моєму конкретному випадку (редактор, схожий на дзеркало з кодом) набагато простіше виконувати один великий регулярний вираз, ніж чимало замін, як слід, як кожен раз, коли я замінюю тег HTML, щоб обернути вираз, наступний шаблон буде важче орієнтуватися, не впливаючи на сам тег html (і без хорошого огляду, який, на жаль, не підтримується в JavaScript):
.replace(/(\b\d+|null\b)/g, '<span class="number">$1</span>')
.replace(/(\btrue|false\b)/g, '<span class="bool">$1</span>')
.replace(/\b(new|getElementsBy(?:Tag|Class|)Name|arguments|getElementById|if|else|do|null|return|case|default|function|typeof|undefined|instanceof|this|document|window|while|for|switch|in|break|continue|var|(?:clear|set)(?:Timeout|Interval))(?=\W)/g, '<span class="keyword">$1</span>')
.replace(/\$/g, '<span class="dollar">$</span>')
.replace(/([\[\](){}.:;,+\-?=])/g, '<span class="ponctuation">$1</span>')
Використовуйте конструктор з двома парамами та уникайте проблем із записом '/':
var re_final = new RegExp("\\" + ".", "g"); // constructor can have 2 params!
console.log("...finally".replace(re_final, "!") + "\n" + re_final +
" works as expected..."); // !!!finally works as expected
// meanwhile
re_final = new RegExp("\\" + "." + "g"); // appends final '/'
console.log("... finally".replace(re_final, "!")); // ...finally
console.log(re_final, "does not work!"); // does not work
Ви можете сформулювати джерело регулярних виразів як з прямого, так і з класу RegExp:
var xxx = new RegExp(/abcd/);
var zzz = new RegExp(xxx.source + /efgh/.source);
простішим способом для мене було б об'єднати джерела, напр .:
a = /\d+/
b = /\w+/
c = new RegExp(a.source + b.source)
значення c призведе до:
/ \ d + \ w + /
let regexSegment1 = String.raw`\s*hello\s*`