【问题标题】:Bra size validation with RegExp (US, EU, Japan, Australia)使用 RegExp 验证胸罩尺寸(美国、欧盟、日本、澳大利亚)
【发布时间】:2020-09-10 02:13:32
【问题描述】:

我想检查输入是否是有效的胸罩测量值。在美国,胸罩尺寸用偶数 28-48 和字母 A-I、AAA、AA、DD、DDD、HH 或 HHH 书写。欧盟、日本和澳大利亚使用不同的数字和模式,例如。 90C C90 和 DD6。

-我想拆分字母和数字,检查字母在A-I或AA、AAA、DD、DDD、HH或HHH之间,数字是28-48(仅偶数)、60 -115(以 5 为增量,因此 65、70、75 等)或仅 6-28 个偶数。

var input = $("#form_input").val("");

var bust = input.match(/[\d\.]+|\D+/g);

var vol = bust[0];

var band = bust[1];

我可以写一个很长的测试条件:

如果 ((vol > 28 && vol

} else { 错误信息" }```

如何缩短它并使用正则表达式执行上述操作?

【问题讨论】:

  • var input = $("#form_input").val(""); 因此,您将 jquery 对象存储到输入中并将输入值设置为空字符串。这会引发错误,因为 jQuery 对象没有 match() 方法。
  • /(\d{2})([A-I]|A{2,3}|D{2,3}|H{2,3})/
  • 不适用于28AA
  • /(2[89]|3[0-9]|4[0-8])([A-I]|A{2,3}|D{2,3}|H{2,3})//(28|[34][02468])([A-I]|A{2,3}|D{2,3}|H{2,3})/
  • 34AAA 都不工作。

标签: javascript regex validation


【解决方案1】:

替代方案有点长,但是如果缺少某些内容或匹配太多,您可以轻松调整范围。

您可以先使用test 检查模式是否匹配。要获得波段和 vol 匹配,一种选择是从匹配中提取数字或大写字符,因为有匹配例如 90CC90

^(?:(?:28|3[02468]|4[02468])(?:AA?|[BC]|D{1,4}|[E-I])|(?:[6-9][05]|1[01][05])(?:AA?|[BC]|DD?|[E-I])|[A-I](?:[6-9][05]|1[01][05])|(?:[68]|1[02468]|2[0246])(?:AA?|[BC]|DD?|[E-I]))$

说明

  • ^ 字符串开始
  • (?: 替代方案的非捕获组
    • (?:28|3[02468]|4[02468]) 以 2 为步长匹配 28 - 48
    • (?:AA?|[BC]|D{1,4}|[E-I]) 匹配 AA、A、B、C,1-4 次 D 或范围 E-I
    • |或者
    • (?:[6-9][05]|1[01][05]) 匹配 60 - 115 个 5 的脚背
    • (?:AA?|[BC]|DD?|[E-I]) 匹配 AA、A、B、C DD、D 或范围 E-I
    • |或者
    • [A-I](?:[6-9][05]|1[01][05]) 匹配范围 A-I 和数字 60 - 115,步长为 5
    • |或者
    • (?:[68]|1[02468]|2[0246]) 以 2 为步长匹配 6 - 26
    • (?:AA?|[BC]|DD?|[E-I]) 匹配 AA、A、B、C、DD、D 或范围 E-I
  • )关闭交替
  • $字符串结束

Regex demo

const pattern = /^(?:(?:28|3[02468]|4[02468])(?:AA?|[BC]|D{1,4}|[E-I])|(?:[6-9][05]|1[01][05])(?:AA?|[BC]|DD?|[E-I])|[A-I](?:[6-9][05]|1[01][05])|(?:[68]|1[02468]|2[0246])(?:AA?|[BC]|DD?|[E-I]))$/;
const str = `28A
28AA
30B
34AA
36DDDD
D70
I115
A70
H80
6AA
26I
`;

str.split('\n').forEach(s => {
  if (pattern.test(s)) {
    console.log(`Match: ${s}`);
    let vol = s.match(/\d+/)[0];
    let band = s.match(/[A-Z]+/)[0];
    console.log(`vol: ${vol}`);
    console.log(`band: ${band}`);
    console.log("---------------------------------------");
  }
})

【讨论】:

  • 感谢您提供详细信息。非常需要!
  • 解释帮助很大。我会提供更新,以便每个人都可以看到成品。也许再过一周左右。
【解决方案2】:
^(((([0-4])(0|2|4|6|8))|(6|8))|(((6|7|8|9)(0|5))|(1[01][05])))((AAA)|(AA)|(DD)|(DDD)|(HH)|(HHH)|[A-I])$

证明所有有效尺寸都匹配,而所有 100_464 样本无效尺寸不匹配:

const validNumbers = Array
  .from({ length: 22 }, (_, i) => 6 + (i * 2))
  .concat(Array.from({ length: 12 }, (_, i) => 60 + (i * 5)));
  
const validLetters = [
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
  'AAA', 'AA', 'DD', 'DDD', 'HH', 'HHH'
];

const validSizes = validNumbers.map((number) => validLetters
  .map((letter) => number + letter))
  .flat();

const invalidNumbers = Array
  .from({ length: 1_000 }, (_, i) => i)
  .filter((n) => !validNumbers.includes(n))

const invalidLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
  .map((letter) => Array.from({ length: 4 }, (_, i) => letter.repeat(i + 1)))
  .flat();

const invalidSizes = invalidNumbers.map((number) => invalidLetters
  .map((letter) => number + letter))
  .flat();

const regex = /^(((([0-4])(0|2|4|6|8))|(6|8))|(((6|7|8|9)(0|5))|(1[01][05])))((AAA)|(AA)|(DD)|(DDD)|(HH)|(HHH)|[A-I])$/;

const falsePositives = invalidSizes.filter((size) => regex.test(size));
console.log({ falsePositives });
console.log({ validSizes: validSizes.map((size) => ({ size, isValid: regex.test(size) })) });

【讨论】:

  • 令人印象深刻!我还必须考虑用户输入将被保留,因此它可能是 90C 或 C90。出于这个原因,大部分的正则表达式不得不被废弃。欢迎对此提出反馈:playcode.io/668437
猜你喜欢
  • 1970-01-01
  • 2018-03-03
  • 2015-06-04
  • 1970-01-01
  • 2020-05-29
  • 2011-06-08
  • 2015-07-13
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多