动态创建正则表达式组以匹配低于或高于所需值的模式
Dynamically create RegExps groups to match patterns lower than or greater than a desired value
我创建了两个 JavaScript
函数来动态创建 RegExps
匹配小于或大于参数中发送的数字的组。这些函数的目的是做一些类似 this or this 的事情,但是动态地,我需要它来构建一个应用程序 RegExps
,这段代码创建了一个匹配特定数字组的组,稍后你可以使用返回小组完成你的最后 RegExp
.
这是创建 RegExp
以查找大于所需值的形态的函数:
//Find greater than numbers
function getGreaterUintRegEx(n) {
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "9":
a.push((Number(s.slice(0, t - i)) + 1) + "0" + (new Array(i)).join("\d"));
break;
case "8":
a.push(s.slice(0, t - i) + "9" + (new Array(i)).join("\d"));
break;
default:
a.push(s.slice(0, t - i) + "[" + (Number(s.charAt(t - i)) + 1) + "-9]" + (new Array(i)).join("\d"));
}
}
a.push("\d{" + (t + 1) + ",}");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
使用示例:
var regstr = getGreaterUintRegEx(124);
// (12[5-9]|1[3-9]\d|[2-9]\d\d|\d{4,})
var regstr = getGreaterUintRegEx(500);
// (50[1-9]|5[1-9]\d|[6-9]\d\d|\d{4,})
这里是创建 RegExp
以查找低于所需值的形态的函数:
//Find lower than numbers
function getLowerUintRegEx(n) {
if (n == 0) return false;
if (n == 1) return "(0)";
if (n > 0 && n < 10) return "[0-" + (n - 1) + "]";
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "0":
a.push(((s.slice(0, t - i) == "1") ? "" : (Number(s.slice(0, t - i)) - 1)) + "9" + (new Array(i)).join("\d"));
break;
case "1":
a.push("[1-9]" + (new Array(i - 1)).join("\d"));
break;
default:
a.push(s.slice(0, t - i) + "[0-" + (Number(s.charAt(t - i)) - 1) + "]" + (new Array(i)).join("\d"));
}
}
if (t - 1 > 1) a.push("\d{1," + (t - 1) + "}");
a.push("0");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
使用示例:
var regstr = getLowerUintRegEx(498);
// (49[0-7]|4[0-8]\d|[0-3]\d\d|\d{1,2}|0)
var regstr = getLowerUintRegEx(125);
// (12[0-4]|1[0-1]\d|[1-9]\d|\d{1,2}|0)
我想让这些功能更简单、更慢。大数字需要一秒钟以上。还有其他更简单的方法吗?有人知道步骤更少的稳健算法吗?
方法复杂,你的方法。以及限制方式。
function getInts(str){
return String(str).match(/[+-]?\d+/g).map(Number);
}
function greaterThan(w){
return function(v){ return v > w }
}
function lowerThan(w){ //
return function(v){ return v < w }
}
getInts(someString).filter( greaterThan(473) )
或更通用的方法:
var is = (function(is){
for(var key in is) is[key] = Function("w", "return function(v){return v " + is[key] + " w}");
return is;
})({
eq: "===",
neq: "!==",
gt: ">",
lt: "<",
gteq: ">=",
lteq: "<="
});
is.typeof = function(w){ return function(v){ return typeof v === w }};
getInts(someString).filter( is.lt(92) );
这不是我解决问题的方法,但您不是在寻找更好的解决方案,而是实际上想要审查您的代码、建议和优化,以提供与原始功能相同的功能(有效代码)。
无论如何,下面是一个建议。代码可读性更强,我无意测试其性能。
var reduceRight = Function.prototype.call.bind(Array.prototype.reduceRight);
//Find greater than numbers
function getGreaterUintRegEx(n) {
var s = String(n);
var t = s.length - 1;
var a = reduceRight(s, function(acc, v, i) {
var x = s.slice(0, i);
if (v === '9') {
x = Number(x) + 1 + '0';
} else if (v === '8') {
x += '9';
} else {
x += '[' + (Number(v) + 1) + '-9]';
}
acc.push(x + '\d'.repeat(t - i));
return acc;
}, []);
a.push('\d{' + (t + 2) + ',}');
return '(' + a.join('|') + ')';
}
//Find greater than numbers: original
function getGreaterUintRegEx1(n) {
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "9":
a.push((Number(s.slice(0, t - i)) + 1) + "0" + (new Array(i)).join("\d"));
break;
case "8":
a.push(s.slice(0, t - i) + "9" + (new Array(i)).join("\d"));
break;
default:
a.push(s.slice(0, t - i) + "[" + (Number(s.charAt(t - i)) + 1) + "-9]" + (new Array(i)).join("\d"));
}
}
a.push("\d{" + (t + 1) + ",}");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
var out = document.getElementById('out');
for (var i = 0; i < 100000; i += 1) {
var suggested = getGreaterUintRegEx(i);
var original = getGreaterUintRegEx1(i);
if (suggested !== original) {
var txt = suggested + '!==' + original;
out.textContent = txt;
throw new Error(txt);
}
}
out.textContent = suggested + '\n' + original + '\nSame results';
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.1/es6-shim.js"></script>
<pre id="out"></pre>
只需删除不必要的数据结构(每次调用都会创建几个 Array
并且需要一个 Function
、none),您将获得很大的加速。
这里重写了 getGreaterUintRegEx
:
function getGreaterUintRegEx(n) {
var nStr = String(n);
var len = nStr.length;
var result = '(';
var ds = '';
var i;
for (i = len - 1; i >= 0; i--) {
switch (nStr.charAt(i)) {
case '9': result += `${+nStr.slice(0, i) + 1}0${ds}|`; break;
case '8': result += `${nStr.slice(0, i)}9${ds}|`; break;
default: result += `${nStr.slice(0, i)}[${+nStr.charAt(i) + 1}-9]${ds}|`;
}
ds += '\d';
}
return `${result}\d{${len + 1},})`;
}
我使用 ES6 模板字符串只是为了提高可读性。它们目前在常绿浏览器中受支持,但如果您想支持 IE11,则需要将它们换成旧的 '' + ''
。
我创建了两个 JavaScript
函数来动态创建 RegExps
匹配小于或大于参数中发送的数字的组。这些函数的目的是做一些类似 this or this 的事情,但是动态地,我需要它来构建一个应用程序 RegExps
,这段代码创建了一个匹配特定数字组的组,稍后你可以使用返回小组完成你的最后 RegExp
.
这是创建 RegExp
以查找大于所需值的形态的函数:
//Find greater than numbers
function getGreaterUintRegEx(n) {
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "9":
a.push((Number(s.slice(0, t - i)) + 1) + "0" + (new Array(i)).join("\d"));
break;
case "8":
a.push(s.slice(0, t - i) + "9" + (new Array(i)).join("\d"));
break;
default:
a.push(s.slice(0, t - i) + "[" + (Number(s.charAt(t - i)) + 1) + "-9]" + (new Array(i)).join("\d"));
}
}
a.push("\d{" + (t + 1) + ",}");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
使用示例:
var regstr = getGreaterUintRegEx(124);
// (12[5-9]|1[3-9]\d|[2-9]\d\d|\d{4,})
var regstr = getGreaterUintRegEx(500);
// (50[1-9]|5[1-9]\d|[6-9]\d\d|\d{4,})
这里是创建 RegExp
以查找低于所需值的形态的函数:
//Find lower than numbers
function getLowerUintRegEx(n) {
if (n == 0) return false;
if (n == 1) return "(0)";
if (n > 0 && n < 10) return "[0-" + (n - 1) + "]";
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "0":
a.push(((s.slice(0, t - i) == "1") ? "" : (Number(s.slice(0, t - i)) - 1)) + "9" + (new Array(i)).join("\d"));
break;
case "1":
a.push("[1-9]" + (new Array(i - 1)).join("\d"));
break;
default:
a.push(s.slice(0, t - i) + "[0-" + (Number(s.charAt(t - i)) - 1) + "]" + (new Array(i)).join("\d"));
}
}
if (t - 1 > 1) a.push("\d{1," + (t - 1) + "}");
a.push("0");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
使用示例:
var regstr = getLowerUintRegEx(498);
// (49[0-7]|4[0-8]\d|[0-3]\d\d|\d{1,2}|0)
var regstr = getLowerUintRegEx(125);
// (12[0-4]|1[0-1]\d|[1-9]\d|\d{1,2}|0)
我想让这些功能更简单、更慢。大数字需要一秒钟以上。还有其他更简单的方法吗?有人知道步骤更少的稳健算法吗?
方法复杂,你的方法。以及限制方式。
function getInts(str){
return String(str).match(/[+-]?\d+/g).map(Number);
}
function greaterThan(w){
return function(v){ return v > w }
}
function lowerThan(w){ //
return function(v){ return v < w }
}
getInts(someString).filter( greaterThan(473) )
或更通用的方法:
var is = (function(is){
for(var key in is) is[key] = Function("w", "return function(v){return v " + is[key] + " w}");
return is;
})({
eq: "===",
neq: "!==",
gt: ">",
lt: "<",
gteq: ">=",
lteq: "<="
});
is.typeof = function(w){ return function(v){ return typeof v === w }};
getInts(someString).filter( is.lt(92) );
这不是我解决问题的方法,但您不是在寻找更好的解决方案,而是实际上想要审查您的代码、建议和优化,以提供与原始功能相同的功能(有效代码)。
无论如何,下面是一个建议。代码可读性更强,我无意测试其性能。
var reduceRight = Function.prototype.call.bind(Array.prototype.reduceRight);
//Find greater than numbers
function getGreaterUintRegEx(n) {
var s = String(n);
var t = s.length - 1;
var a = reduceRight(s, function(acc, v, i) {
var x = s.slice(0, i);
if (v === '9') {
x = Number(x) + 1 + '0';
} else if (v === '8') {
x += '9';
} else {
x += '[' + (Number(v) + 1) + '-9]';
}
acc.push(x + '\d'.repeat(t - i));
return acc;
}, []);
a.push('\d{' + (t + 2) + ',}');
return '(' + a.join('|') + ')';
}
//Find greater than numbers: original
function getGreaterUintRegEx1(n) {
var s = String(n);
var t = s.length,
a = [];
for (var i = 1; i < t + 1; i++) {
switch (s.charAt(t - i)) {
case "9":
a.push((Number(s.slice(0, t - i)) + 1) + "0" + (new Array(i)).join("\d"));
break;
case "8":
a.push(s.slice(0, t - i) + "9" + (new Array(i)).join("\d"));
break;
default:
a.push(s.slice(0, t - i) + "[" + (Number(s.charAt(t - i)) + 1) + "-9]" + (new Array(i)).join("\d"));
}
}
a.push("\d{" + (t + 1) + ",}");
a = a.filter(function(s, i) {
return a.indexOf(s) == i;
});
return "(" + a.join("|") + ")";
}
var out = document.getElementById('out');
for (var i = 0; i < 100000; i += 1) {
var suggested = getGreaterUintRegEx(i);
var original = getGreaterUintRegEx1(i);
if (suggested !== original) {
var txt = suggested + '!==' + original;
out.textContent = txt;
throw new Error(txt);
}
}
out.textContent = suggested + '\n' + original + '\nSame results';
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.1/es6-shim.js"></script>
<pre id="out"></pre>
只需删除不必要的数据结构(每次调用都会创建几个 Array
并且需要一个 Function
、none),您将获得很大的加速。
这里重写了 getGreaterUintRegEx
:
function getGreaterUintRegEx(n) {
var nStr = String(n);
var len = nStr.length;
var result = '(';
var ds = '';
var i;
for (i = len - 1; i >= 0; i--) {
switch (nStr.charAt(i)) {
case '9': result += `${+nStr.slice(0, i) + 1}0${ds}|`; break;
case '8': result += `${nStr.slice(0, i)}9${ds}|`; break;
default: result += `${nStr.slice(0, i)}[${+nStr.charAt(i) + 1}-9]${ds}|`;
}
ds += '\d';
}
return `${result}\d{${len + 1},})`;
}
我使用 ES6 模板字符串只是为了提高可读性。它们目前在常绿浏览器中受支持,但如果您想支持 IE11,则需要将它们换成旧的 '' + ''
。