【问题标题】:Regex Rules for First and Second Character第一个和第二个字符的正则表达式规则
【发布时间】:2011-03-29 08:10:24
【问题描述】:

我在遵循 javascript 和 php 的正则表达式规则方面需要帮助。

JS

var charFilter = new RegExp("^[A|B].+[^0123456789]$");

PHP

if (!preg_match('/^[A|B].+[^0123456789]$/', $data_array['sample_textfield'])) {

这个正则表达式是关于

第一个字符必须以 A 或 B 开头,最后一个字符不能包含 0 到 9。

我有另一个验证,字符必须是最少 3 个字符和最多 6 个数字。

我要添加的新规则是,如果第一个字母是 A,第二个字符不能是 C。

这意味着

ADA(有效) ACA(无效)

所以我像这样更改了正则表达式代码

JS

var charFilter = new RegExp("^(A[^C])|(B).+[^0123456789]$");

PHP

if (!preg_match('/^(A[^C])|(B).+[^0123456789]$/', $data_array['sample_textfield'])) {

它适用于第一个和第二个字符。如果我输入

ACA(它说无效),但如果我输入 AD3(它说有效),它不再检查最后一个字符。最后一个字符不能包含 0 到 9 的数字,但它显示为有效。

谁能帮我修复那个正则表达式代码?非常感谢。

【问题讨论】:

  • 请注意,[A|B] 匹配以下之一:A|B| 并不意味着 OR 在字符类中!

标签: php javascript regex


【解决方案1】:

把你所有的要求放在一起,看来你想要这个模式:

^(?=.{3,6}$)(?=A(?!C)|B).+\D$

即:

  • 从字符串^的开头
  • 我们可以断言字符串 (?=.{3,6}$) 的末尾有 3 到 6 个“任意”字符
  • 我们也可以断言它以A开头而不是C,或者以B开头(?=A(?!C)|B)
  • 整件事并没有以数字结尾.+\D$

这将匹配 (as seen on rubular.com):

= match =         = no match =
ADA               ACA
ABCD              AD3
ABCDE             ABCDEFG
ABCDEF
A123X
A   X

请注意,.+\D 允许使用空格。如果你坚持没有空格,你可以使用例如(?=\S{3,6}$) 在模式的第一部分。

(?=…)积极的前瞻;它断言可以匹配给定的模式。 (?!…)否定前瞻;它断言给定的模式可以匹配。

参考文献

相关问题


关于交替优先

原始模式的问题在于误解了交替 | 说明符的优先级。

考虑以下模式:

this|that-thing

此模式由两个替代项组成,一个匹配"this",另一个匹配"that-thing"。将此与以下模式进行对比:

(this|that)-thing

现在这个模式匹配"this-thing""that-thing",感谢分组(…)。巧合的是,它还创建了一个 capturing 组(将捕获"this""that")。如果您不需要捕获功能,但需要分组方面,请使用非捕获组 ``(?:…)`。

另一个需要分组的例子是重复:ha{3} 匹配 "haaa",但 (ha){3} 匹配 "hahaha"

参考文献

【讨论】:

    【解决方案2】:

    您的 OR 反对错误的分组。试试:

    ^((A[^C])|(B)).+[^0123456789]$
    

    【讨论】:

    • 您好,感谢您的代码,我认为这是错误的,因为如果我输入 ACA(无效)并且它是正确的,但是如果我输入 ABC(仍然显示为无效,实际上它应该显示有效)但如果我输入超过 3 个字符,则显示有效。有什么想法吗?
    【解决方案3】:

    在 jasonbars 解决方案中,它与 ABC 不匹配的原因是因为它需要 A 后跟非 C,即两个字符,后跟一个或多个任意字符,后跟一个非数字。因此,如果字符串以 A 开头,则最小长度为 4。您可以使用前瞻断言来解决此问题。

    PHP

    $pattern = '#^(A(?=[^C])|B).+\D$#';
    

    【讨论】:

    • 我觉得(?!C)(?=[^C])好。
    • 确实,我发帖后也是这么想的,但是懒得编辑了:)。
    【解决方案4】:

    我觉得应该是这样的

    /^(A[^C]|B.).*[^0-9]$/
    

    试试这个测试代码

    $test = "
        A
        B
        AB
        AC
        AAA
        ABA
        ACA
        AA9
        add more
    ";
    $pat = '/^(A[^C]|B.).*[^0-9]$/';
    foreach(preg_split('~\s+~', $test) as $p)
        printf("%5s : %s\n<br>", $p, preg_match($pat, $p) ? "ok" : "not ok");
    

    【讨论】:

    • 您好,感谢您的代码。我试过了,不管我输入什么,它一直显示无效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多