我正在使用字母数字排序进行正则表达式解析来比较两个参数。首先,我应该忽略前导零以进行令牌比较。但是如果所有令牌都相等,则带有前导零的标记较小 所以我做一个像/(\ D | [1-9])/这样的正则表达式并递归解析(比较第一个令牌,如果相等,则通过regex.exec(arg1,arg2)传回新的字符串减去前导相等的令牌
但是如果一切都是平等的,我想用regex /(\ D | 0 * \ d)/再次对整个事情进行处理以捕获前导零。我试着通过返回一个公式来做到这一点。原来变成了: 函数(arg1,arg2,orig1,orig2);
然后我返回
函数比较(arg1new,arg2new,arg1,arg2)
但是在循环迭代中会发生的事情是,arg1new变为arg1,它会在orig1点返回...所以我丢失了原始的函数参数,而只是一个循环后面的相同参数。
有没有办法通过所有递归来保存原始参数...并且仅在结束时调用?
示例:
function alphanumericLess(s1, s2, orig1, orig2) {
console.log(s1,s2);
if(s1.length<1 && s2.length>=1){ //if 1st string is shorter
return true;
}
var regex = /(\D|[1-9])(.*)/;
var leadS1 = regex.exec(s1); //parse string1 ignoring leading zeroes
var leadS2 = regex.exec(s2); //parse string2 ignoring leading zeroes
if(leadS1[1]==leadS2[1]){
console.log('if equals loop');
return alphanumericLess(leadS1[2],leadS2[2],s1,s2);
} else if(leadS1[1]<leadS2[1]){
return true;
} else return false; //here is where I want to then re-run the recursion with /(\D|0*\d)/ to capture the leading zeroes comparison scenario
}
答案 0 :(得分:0)
一些显示示例的伪代码:
function keep (a,b) {
if (a == b) {
return b;
}
else {
return keep(a + 1, b);
}
}
keep(1, 5);
B一直向上传递,然后再一次向下......
答案 1 :(得分:0)
您可以通过在现有函数中创建一个本地函数来解决这个问题,这些函数将被递归调用而不是现有函数。然后你可以用两种不同的方式调用那个局部函数来启动递归两次。
您当前的代码也存在一些问题:
sort
回调所需的签名,即当第一个参数应该在第二个参数之前排序时它应该返回一个负数,当它们相等时它应该返回0,如果第一个应该在第二个之后排序,则为1。12AB' and
123AB`中,比较应该在12和123之间,而不是&# 39; A&#39;和3. 这是一个解决方案:
function alphanumericLess(s1, s2) {
// Use a local function for the recursion, so it can be called twice
function recurse(s1, s2) {
if (!s1.length || !s2.length) { // test ALL end conditions
// Don't return a boolean, but a numerical value
return s1.length - s2.length;
}
// Match multiple characters/digits as one part, deal with the 0 exclusion
// before calling the recurse function:
var regex = /(\D+|\d+)(.*)/;
var leadS1 = regex.exec(s1);
var leadS2 = regex.exec(s2);
if (leadS1[1] === leadS2[1]) { // Use strict comparison where possible
return recurse(leadS1[2], leadS2[2]);
} // After an if-return, else is not needed
// As parts can have different lengths, use appropriate comparison method,
// and return a number that represents the comparison result
if (isNaN(leadS1[1]) || isNaN(leadS2[1])) {
return leadS1[1].localeCompare(leadS2[1]);
}
// In the numerical case, if equal, give precedence to the
// longest representation (zero-padded):
return +leadS1[1] - +leadS2[1] || leadS2[1].length - leadS1[1].length;
}
// First call above function with leading zeroes removed.
// If that yields equality, call it again without such removal:
return recurse(s1.replace(/\b0+/g, ''), s2.replace(/\b0+/g, ''))
|| recurse(s1, s2);
}
console.log(alphanumericLess('012Ab3X0', '12Ab3X0')); // negative => order is correct
console.log(alphanumericLess('Ab30X0', 'Ab3X0')); // positive => order is reversed
console.log(alphanumericLess('Ab30X0', 'Ab30X0')); // zero => equal
// Use in sort: output is [ "001A", "1A", "2A", "B0999", "B0999X", "B999X" ]
console.log(['B999X', '1A', 'B0999', '001A', 'B0999X', '2A'].sort(alphanumericLess));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
在第一次扫描中忽略前导零的代码不在递归之外:它是通过一次删除那些前导零来完成的。这样两个扫描的递归函数是相同的,只是参数不同。
在递归函数的每次调用中执行正则表达式效率不高。在进入递归之前对字符串进行拆分会更有效。当然,非递归函数会更有效。
最后,自然排序通常也不区分大小写。您可能也希望将该逻辑放在您的函数中。