【问题标题】:How to dynamically combine two regex? [duplicate]如何动态组合两个正则表达式? [复制]
【发布时间】:2019-12-03 17:43:03
【问题描述】:

两个正则表达式可以组合吗?喜欢它应该匹配这个正则表达式或其他。理想情况下排他(xor)。

例如,我想根据固定电话号码正则表达式和手机号码正则表达式验证电话号码。

我希望我能做这样的事情,但它不起作用:

const landlinePhoneRegExp = /(^1300\d{6}$)|(^1800|1900|1902\d{6}$)|(^0[2|3|7|8]{1}[0-9]{8}$)|(^13\d{4}$)|(^04\d{2,3}\d{6}$)/
const mobilePhoneRegExp = /^04[0-9 ]+/
const stripOutDelimiters = regex => etc...

const phoneRegExp = `/${stripOutDelimiters(landlinePhoneRegExp)}|${stripOutDelimiters(mobilePhoneRegExp)}/`,

更新:我忘了补充说我正在使用 Yup 库进行验证!代码如下所示:

const validationSchema = (t, i18n) => Yup.object.shape({
  phone: Yup.string()
    .required(t('formValidationPhoneRequired'))
    .matches(localeRegex[i18n.language].phoneRegExp, t('formValidationPhoneInvalid'))
})

这解释了为什么我试图将两个正则表达式动态组合成一个,就像上面的非工作示例一样。

我已经关注docs 有一段时间了,但似乎没有办法做到这一点。也许lazy() 会很有用,但显然我不能使用string.matches()...除非我将(landlineMatch || mobileMatch) 与boolean() 匹配,但我该怎么做呢?

phone: Yup.lazy((value) => {
  const landlineMatch = value.match(localeRegex[i18n.language].landlinePhoneRegExp)
  const mobileMatch = value.match(localeRegex[i18n.language].mobilePhoneRegExp)

  return Yup.string()
    .required(t('formValidationPhoneRequired'))
    .matches( ??? , t('formValidationPhoneInvalid'))
})

【问题讨论】:

  • 单独测试会容易得多。
  • OP 已经明确表示他们希望将这些动态地与 Javascript 和 XOR 逻辑结合起来,所以我认为这两个都不能回答这个问题。
  • @Andrew 确实如此,我们在这里谈论的动态如何,AI?
  • 请注意,(^1800|1900|1902\d{6}$) 匹配以1800 开头且后面有任何字符的字符串(即1800abcg*$ù^pihybncisgf456),或在中间某处有1900 的字符串(即abcdef1900xrs654ehrbt84)或以1902 结尾的字符串,后跟6 位数字(即xyz1234561902123456
  • 实际问题归结为^(?:(04\d{8,9})|(04[0-9 ]+))$。最后一个交替与第一个重叠。换句话说,第一个是最后一个的子集。那么它不符合异或异或的条件。所需要的只是子集的正常 OR。

标签: javascript regex yup


【解决方案1】:

你差不多完成了,你只需要测试它们是否匹配。

要测试一个字符串是否匹配,只需使用String.prototype.match():

landlineMatch = str.match(landlinePhoneRegExp)
mobileMatch = str.match(mobilePhoneRegExp)

逻辑异或测试没有捷径,您只需像这样使用&&|| 的组合:

(landlineMatch || mobileMatch) && !(landlineMatch && mobileMatch)

【讨论】:

  • (landlineMatch && !mobileMatch) || (mobileMatch && !landlineMatch)
  • 或者简单地说if (!landlineMatch !== !mobileMatch)(xor 等价于两个表达式计算不同的布尔值,一个为真,另一个为假)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
相关资源
最近更新 更多