【问题标题】:preg_match substring only if is validpreg_match 子串仅当有效时
【发布时间】:2014-08-07 10:34:42
【问题描述】:

只有在有效的情况下,我才需要从电子邮件主题中提取子字符串。有效的子字符串如下:

ab-2011-0023adac-2011-0023ad.r1,只允许使用两个破折号,第二个破折号后的字母数量不同,但只能是带一个点或不带点的字母数字。

我写了这个,但是如果我在第二个破折号后面放了一个非法字符,则正则表达式返回部分子字符串不为空

/([a-z0-9]{0,3}[-]\d{4}[-][a-z0-9.]+)\S/i

即:"this is an email with ab-2011-0023:ad document",我希望正则表达式返回空数组而不是 [0] => ab-2011-0023

【问题讨论】:

    标签: php preg-match substring extract


    【解决方案1】:

    您的 reg exp 不正确。 1. 永远不要在像这样的符号类中使用一个文字 [-]。你应该逃避它 - 但点头添加到符号类。 2. [a-z0-9.]+ 这一段匹配字符串“........”。所以,这是不正确的。 3. 最后你使用 \S 作为分隔符(匹配除空格以外的所有内容)。

    我的建议是像这样使用 smth(如果您的 reg exp 引擎支持 Negative Lookbehind)

    /[a-z\d]{0,3}\-\d{4}\-(?:[a-z\d]+|(?<!\.)\.)+\s/i
    

    example

    【讨论】:

    • 您的示例工作正常,但您的答案有误。正确的是:([a-z\d]{0,3}\-\d{4}\-(?:[a-z\d]+|(?
    • “错误” - 你的意思是缺少保留括号?如果您只想检查字符串(匹配),则无需使用它们。在 regex101 的演示中,它曾经突出显示匹配项。欢迎。
    【解决方案2】:

    尝试转义(. 匹配任何字符),并强制匹配整个字符串($ 表示结束,^ 表示开始):

    /^[a-z0-9]{0,3}[\-]\d{4}[\-][a-z0-9\.]+$/i
    

    例子:

    $subject = "ac-2011-0023ad.r1";
    $subject2 = "ab-2011-0023:ad";
    
    if(preg_match("/^[a-z0-9]{0,3}[\-]\d{4}[\-][a-z0-9\.]+$/i",$subject,$match)) {
      echo "Found : ".$match[0]."\n";
    }
    
    if(preg_match("/^[a-z0-9]{0,3}[\-]\d{4}[\-][a-z0-9\.]+$/i",$subject2,$match)) {
      echo "Found : ".$match[0]."\n";
    }
    

    【讨论】:

    • 如果-是字符类中的第一个或最后一个字符,也不是字符类中的点,则无需转义。
    【解决方案3】:

    只需在你的正则表达式周围添加空格:

    /(?:\s|)([a-z0-9]{0,3}[-]\d{4}[-][a-z0-9]+(?:\.[a-z0-9]+)?)(?:\s|)/i
    

    【讨论】:

    • @user3917799:你能解释一下它在哪种方面不起作用吗?
    • 我在这里测试过:regex101.com/r/mK0wU8/1,这不是我在我的问题中要求的。无论如何,谢谢,我很感激任何帮助。
    猜你喜欢
    • 2012-09-13
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多