javascript - 如何将此 JavaScript 逻辑移植为要在 PHP 中使用的单行 RegEx?
问题描述
我正在尝试重新创建以下条件来验证要与 PHP 一起使用的单个 RegEx 中的字符串语法。如果这些条件都满足,那么最快的正则表达式是什么,返回TRUE ?
- 字符串不能为空
- 总字符串长度:
>= 3
和<= 16
字符 - 字符串中允许的字符:
a-z
,0-9
,-
,.
- 不允许大写字母
- 第一个字符必须是小写字母:
a-z
- 最后一个字符必须是小写字母或数字:
a-z
或0-9
-
字符串中的任何位置都不能有两个连续的连字符
Bonus Trickyness:如果存在点/句点.
,则字符串将使用s.
作为分隔符进行分段。这些“段”有特殊的规则:
- 所有以前的规则也仍然适用于整个字符串
- 段必须以字母开头:
a-z
- 段以字母或数字结尾:
a-z
0-9
- Segment 只能有字母、数字或连字符:
a-z
0-9
-
- 段必须是
=> 3
字符长
这个“段”逻辑真的让我陷入了循环(不是双关语)。我不确定如何将所有内容合并在一起。
这是实现目标的 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;
}
谢谢!
解决方案
您可以使用正向预读来断言长度,包括第一个和最后一个字符,并使用另一个负向预读来断言不是 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))*$
推荐阅读
- if-statement - 使用 if-then-else 打印文件和目录并说明它是文件还是目录
- c++ - 如何将 `void *` 类型更改为 `string` 类型
- python - Flask 虚拟环境和环境变量
- json - 如何在akka-Http中返回JSON而不是Case Class
- batch-file - 如何使用批处理将日期和时间写入同一行的日志文件
- android - 将联系人图像添加到 MessagingStyle 通知“人员”
- css - 从 JSON 中提取的图像未显示在网格中
- java - 在 Java 中增加数组大小的同时向数组添加值
- jquery - 如何使用 jquery 在 ckeditor 中显示 JSON 响应值?
- arduino - DOMException 声明 WebUSB 接口