首页 > 解决方案 > 如何将此 JavaScript 逻辑移植为要在 PHP 中使用的单行 RegEx?

问题描述

我正在尝试重新创建以下条件来验证要与 PHP 一起使用的单个 RegEx 中的字符串语法。如果这些条件都满足,那么最快的正则表达式是什么,返回TRUE ?

Bonus Trickyness:如果存在点/句点.,则字符串将使用s.作为分隔符进行分段。这些“段”有特殊的规则:

这个“段”逻辑真的让我陷入了循环(不是双关语)。我不确定如何将所有内容合并在一起。


这是实现目标的 JavaScript 示例。我在 PHP 中工作,需要一个单行 RegEx,如果满足所有条件,它将验证 TRUE。我不需要逻辑来返回失败的原因(超出范围)。我只需要一个TRUE/FALSE正则表达式。留下这个片段以防万一:

export function validateAccountName(value) {
  let i, label, len, suffix;

  suffix = "Account name should ";
  if (!value) {
    return suffix + "not be empty.";
  }
  const length = value.length;
  if (length < 3) {
    return suffix + "be longer.";
  }
  if (length > 16) {
    return suffix + "be shorter.";
  }
  if (/\./.test(value)) {
    suffix = "Each account segment should ";
  }
  const ref = value.split(".");
  for (i = 0, len = ref.length; i < len; i++) {
    label = ref[i];
    if (!/^[a-z]/.test(label)) {
      return suffix + "start with a letter.";
    }
    if (!/^[a-z0-9-]*$/.test(label)) {
      return suffix + "have only letters, digits, or dashes.";
    }
    if (/--/.test(label)) {
      return suffix + "have only one dash in a row.";
    }
    if (!/[a-z0-9]$/.test(label)) {
      return suffix + "end with a letter or digit.";
    }
    if (!(label.length >= 3)) {
      return suffix + "be longer";
    }
  }
  return null;
}

谢谢!

标签: javascriptregex

解决方案


您可以使用正向预读来断言长度,包括第一个和最后一个字符,并使用另一个负向预读来断言不是 2 个连续的连字符。

^(?=[a-z][a-z\d.-]{1,14}[a-z\d]$)(?!.*--)[a-z\d-]+(?:\.[a-z][a-z\d-]+[a-z\d])*$

模式匹配

  • ^字符串的开始
  • (?=[a-z][a-z\d.-]{1,14}[a-z\d]$)断言 3-16 个字符的正向前瞻,以 az 开头并以 az\d 结尾
  • (?!.*--)否定前瞻断言不--
  • [a-z\d-]+匹配任何列出的字符的 1 次以上(不带点)
  • (?:非捕获组
    • \.[a-z][a-z\d-]+[a-z\d]匹配 a.并重复至少 3 个字符的段,以 az 开头,然后是列出的任何不带点的字符的 1+ 倍,以不带连字符的 az\d 结尾
  • )*关闭非捕获组并可选择重复
  • $字符串结束

正则表达式演示

如果存在点时所有部分至少应为 3 个字符,则可以重复匹配至少 3 个字符,并通过使用重复第一组(?1)查看没有组的模式来稍微缩短模式。

^(?=[a-z][a-z\d.-]{1,14}[a-z\d]$)(?!.*--)([a-z][a-z\d-]+[a-z\d]+)(?:\.(?1))*$

正则表达式演示


推荐阅读