我正在尝试以最有效的方式验证两种不同的方法来识别位置字符串,但是要么可以有轻微的变化,要么在主字符串之前和之后都有一组字符。
有效值:
14-36-085-17 W6
14-36-085-17-W6
14-36-085-17W6
D 096 H 094A15
100 14-36-085-17W6 00
200 D 096 H 094A15 00
所以,我认为它分别是[1-2]0[0-9]
和0[0-9]
。另请注意,前3位数取决于最后2位数,反之亦然。前3位数字只能在那里有最后2位数字,最后2位数字只有前3位数字才能存在。
100 14-36-085-17W6
14-36-085-17W6 00
function func(s)
{
var re = /(^\d{2}-\d{2}-\d{3}-\d{2}W\d$)|(^[A-D] [0-9]{3} [A-L] [0-9]{3}[A-P][0-9]{2}$)/;
return re.test( s );
}
我只假设在第一次验证中使用案例编号1的#3,因为我不确定如何将空格,破折号或任何内容视为有效。
答案 0 :(得分:2)
你真的不想构建一个大的正则表达式 一个人去。它很难阅读,难以维护。和 你的开发人员会在他们需要调试时讨厌你 当你在坎昆度假时喝着玛格丽塔酒 海滩。
因此我建议将其分解为清晰,有意义的 大块(你必须在这里使用你的判断:这是你的 域)。也许是这样的。
var prefix = '([12]0[0-9] )';
var suffix = '( 0[0-9])';
// ? optionally matches the preceding item.
// And don't forget to escape backslashes when creating
// a regexp from a string.
var num1 = '\\d{2}-\\d{2}-\\d{3}-\\d{2}[- ]?W\\d';
var num2 = '[A-D] [0-9]{3} [A-L] [0-9]{3}[A-P][0-9]{2}';
var numbers = '(' + num1 + '|' + num2 + ')';
var pattern = '^(' + prefix + numbers + suffix + '|' + numbers + ')$';
// Instead of creating a large regexp literal all in
// one go, you can build up the regexp pattern from strings,
// and then use RegExp(pattern) to make a regexp instance.
var rx = RegExp(pattern);
现在您可以使用rx
来匹配您的输入
数字。随意使用更有意义的变量名称。
但不要只是把它留在那里。这段代码迫切需要 一些测试。
var testcases = [
{
name: 'Number 1',
tests: [
{input: '14-36-085-17 W6', expected: true},
{input: '14-36-085-17-W6', expected: true},
{input: '14-36-085-17W6', expected: true}
]
},
{
name: 'Number 2',
tests: [
{input: 'D 096 H 094A15', expected: true}
]
},
{
name: 'Number 3',
tests: [
{input: '100 14-36-085-17W6 00', expected: true},
{input: '200 D 096 H 094A15 00', expected: true},
{input: '100 14-36-085-17W6', expected: false},
{input: '14-36-085-17W6 00', expected: false}
]
}
];
让我们试试我们的正则表达式。我正在运行这些 在Chrome中的开发者控制台中进行测试( F12 )。
testcases.forEach(function(testcase){
console.log(testcase.name);
testcase.tests.forEach(function(test){
var result = rx.test(test.input);
console.log(test.input + ' result: ' +
(result ? 'match' : 'no match') +
(result === test.expected ? ' [pass]' : ' [**FAIL**]'));
});
console.log('');
});
输出。
Number 1 14-36-085-17 W6 result: match [pass] 14-36-085-17-W6 result: match [pass] 14-36-085-17W6 result: match [pass] Number 2 D 096 H 094A15 result: match [pass] Number 3 100 14-36-085-17W6 00 result: match [pass] 200 D 096 H 094A15 00 result: match [pass] 100 14-36-085-17W6 result: no match [pass] 14-36-085-17W6 00 result: no match [pass]
大。通过测试可以让您有信心进行更改, 并保证你没有破坏任何东西 做。它让我有信心,我不会给你一个 duff回答。如果你搜索你会看到有很多 可用的自动化单元测试框架 写测试更容易。我给你的是一个基本的 例。但是当你开始跑步时,就会获得巨大的胜利 自动化测试;之后的一切都是精致的。
顺便说一句,这些测试只是您提供的示例 在问题中有效或无效(谢谢!)。 ID 建议您找到更多示例并以此为基础。 希望我已经给你足够的指示,你能够 如果我所做的事情没有结果,那就从这里拿走它 以任何方式充足。
对于正则表达式的回答,这似乎有点过分了,但是 我不能明确表示你使用了一个巨大的 regexp用于验证而不推荐一些机器 让事情变得易于管理。
<小时/> 进一步阅读
答案 1 :(得分:1)
/^([1-2]0[0-9] )?[0-9]{2}-[0-9]{2}-[0-9]{3}-[0-9]{2}[- ]?W[0-9]( 0[0-9])?$/
表示第一个,
/^([1-2]0[0-9] )?[A-D] [0-9] [0-9]{3} [A-L] [0-9]{3}[A-P][0-9]{2}( 0[0-9])?$/
第二个。我对正则表达式并不好,所以我完全有可能把某些东西搞砸了。
答案 2 :(得分:1)
根据你对@ SamuelReid答案评论的要求,正则表达式会变得丑陋。当两个字符串要求相互依赖(在字符串的两侧)时,它变得很难。
/^(?:(?:[12]0\d (?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}) 0\d)|(?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}))$/
/^
(?:
(?:
[12]0\d[ ]
(?:
\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d
|
[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}
)
[ ]0\d
)
|
(?:
\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d
|
[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}
)
)
$/x
(在空格周围添加[]
以强调它们,因为它们很重要并且在自由间隔模式(x标志)中丢失 - 在js中不支持AFAIK)
正如您从“更易于阅读的版本”中看到的那样,基本正则表达式只需在其中一个表达式上添加了[12]0\d[ ]
和[ ]0\d
即可完成两次。
如果需要在字符串中间匹配,只需在正则表达式的两端替换^
和$
锚点\b
:
\b
边界代替^
和$
/\b(?:(?:[12]0\d (?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}) 0\d)|(?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}))\b/
答案 3 :(得分:1)
第一个数字类型可以与以下表达式匹配,这与您已有的非常相似:
/d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d/
^^^^^
added
我正在使用字符集[- ]?
,可选择匹配空格或连字符。
额外字符
匹配左边:
/^[12]0\d /
正确的部分:
/ 0\d$/
现在一起:
/^(?:(?:[12]0\d )(?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2})(?: 0\d)|(?:\d{2}-\d{2}-\d{3}-\d{2}[ -]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2}))$/
让我们清理一下:
var w1 = '\\d{2}-\\d{2}-\\d{3}-\\d{2}[ -]?W\\d',
w2 = '[A-D] \\d{3} [A-L] \\d{3}[A-P]\\d{2}',
words = '(?:' + w1 + '|' + w2 + ')',
prefix = '[12]0\\d ',
suffix = ' 0\\d',
re;
re = new RegExp('^(?:' + prefix + words + suffix + '|' + words + ')$');
答案 4 :(得分:0)
这真的不是那么糟糕(虽然绝对是一个很大的正则表达式)。这应该涵盖两种模式以及开头或结尾的其他可能数字。
以下是您需要的模式:
var re = new RegExp("^([1-2]0\\d )?(\\d{2}-\\d{2}-\\d{3}-\\d{2}[\- ]?W\\d|[A-D] \\d{3} [A-L] \\d{3}[A-P]\\d{2})( 0\\d)?$");
。 。 。或者,或者:
var re = /^([1-2]0\d )?(\d{2}-\d{2}-\d{3}-\d{2}[\- ]?W\d|[A-D] \d{3} [A-L] \d{3}[A-P]\d{2})( 0\d)?$/
其余的代码应该可以正常使用。
编辑:根据我对“全有或全无”的新理解,我更新了我的方法。 。 。我会根据从常见模式构建的两个正则表达式模式进行两项测试。
var sCorePattern = "(\\d{2}-\\d{2}-\\d{3}-\\d{2}[\- ]?W\\d|[A-D] \\d{3} [A-L] \\d{3}[A-P]\\d{2})";
var sSecondaryPattern = "[1-2]0\\d " + sCorePattern + " 0\\d";
var regCorePattern = new RegExp("^" + sCorePattern + "$");
var regSecondaryPattern = new RegExp("^" + sSecondaryPattern + "$");
if (regCorePattern.test(s) || regSecondaryPattern.test(s)) {
. . . do stuff . . .
}
else {
. . . do other stuff . . .
}
对我而言,这是效率和重用的完美结合,同时又不牺牲可读性。 :)