可以这样做吗?
var pattern = /some regex segment/ + /* comment here */ /another segment/;
或者我是否必须使用新RegExp()
语法并连接字符串?我更喜欢使用文字,因为代码更加不言而喻.
以下是如何在不使用正则表达式文字语法的情况下创建正则表达式.这使您可以在变为正则表达式对象之前进行仲裁字符串操作:
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
它只是比单词表达式更多而且只是文字字符串而不是文字正则表达式.
只是随机连接正则表达式对象可能会产生一些不良副作用.改为使用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' : ''));
var m = 'test that abcdef and abcdef has a match?'.match(r3);
// m should contain 2 matches
这还使您能够使用标准RegExp标志保留先前RegExp中的正则表达式标志.
的jsfiddle
我不太同意"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 /",这是正确的.
Logicaly没有必要进行评估,你知道你的表达.你只需要它的来源或如何写它不是必要的价值.至于标志,你只需要使用RegExp的可选参数.
在我的情况下,我运行的问题是^和$在几个表达式中使用我试图连接在一起!这些表达式是整个程序使用的语法过滤器.现在我不想将它们中的一些用在一起来处理PREPOSITIONS的情况.我可能需要"切片"来源以删除开始和结束^(和/或)$ :)干杯,Alex.
问题如果正则表达式包含像\ 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