正则表达式验证第一个和最后一个字符

时间:2012-04-02 07:09:55

标签: php regex

我需要在php中验证字符串不应以连字符(-)开头或结尾。允许的字符为a-zA-Z0-9以及字符串中间任意位置的连字符。

我的这个正则表达式

/^[a-zA-Z0-9-]+$/

验证允许字符的出现期望字符串不应以连字符开头或结尾的条件。我该如何实现这一目标?我是regex的新手。

6 个答案:

答案 0 :(得分:4)

使用否定look ahead and look behind来实现此目标

^(?!-)[a-zA-Z0-9-]+(?<!-)$

here on Regexr

^(?!-)是一个负面的预测断言,确保它不以破折号开头

(?<!-)$是断言背后的负面看法,确保它不会以破折号结束

外观的优点是它们与一个字符不匹配,而只是定义一个断言,这意味着你的字符串也可以有一个长度为1,其中明确要求非破折号作为第一个和最后一个字符的解决方案最小长度为2。

顺便说一下。 a-zA-Z0-9_是预定义的类\w,因此如果您还想允许下划线,则可以更改为:

^(?!-)[\w-]+(?<!-)$

答案 1 :(得分:4)

这应该是你需要的。

/^[a-z0-9]+([a-z0-9-]+[a-z0-9])?$/iD

注意D修饰符。如果没有它,表达式将匹配以新行结尾的字符串。见这里:http://blog.5ubliminal.com/posts/surprises-of-php-regexp-the-d-modifier/。另外,我使用i修饰符不必使用[a-zA-Z0-9]。保持表达更短。

以下是几个例子。当输入字符串以换行结束时,它应该失败,但是如果没有D修饰符,即使使用$锚点,它也会通过:

// Outputs: int(1)
var_dump(preg_match('/^[a-z0-9]+([a-z0-9-]+[a-z0-9])?$/i', "aBc-d\n"));

// Outputs: int(0)
var_dump(preg_match('/^[a-z0-9]+([a-z0-9-]+[a-z0-9])?$/iD', "aBc-d\n"));

答案 2 :(得分:1)

试试这个:

/^[a-zA-Z0-9_]+[a-zA-Z0-9_-]*[a-zA-Z0-9_]+$/

“除了连字符之外的任何一个或任何一个,然后是任何数量的任何东西,包括连字符,然后是一个或多个除了连字符之外的任何东西”。

编辑:如果字符串长度为一个字符,则会失败。对于那个很抱歉。但是你明白了......把它分成子正则表达式。

答案 3 :(得分:1)

  

验证允许字符的出现期望字符串不应以连字符开头或结尾的条件。我该如何实现这一目标?我是regex的新手。

简单地说:~^[^-][a-z0-9-]+[^-]$~应该匹配。它说第一个字符不能是-,然后它说中间部分只能包含[a-z0-9-],然后它说最后一个字符不能是' - '。也就是说,你也可以用substr做这个,我认为你实际上不需要正则表达式。

使用substr:

<?php
$valid = ((substr($str, 0, 1) != '-') && (substr($str, -1) != '-'));

编辑:未读取字母数字加连字符部分,将其包含在正则表达式中。

答案 4 :(得分:0)

使用substr方法。 类似的东西:

if ((substr($str, 0, 1) != '-') && (substr($str, strlen($str)) != '-')){

它在javascript中也可能有类似于charAt的功能,但我现在还不记得了。 (这将为您提供更易读的代码)

答案 5 :(得分:0)

这不是正则表达式,而是根据您的要求运作:

if(
   ctype_alnum($str[0]) && 
   ctype_alnum($str[strlen($str)-1]) && 
   strpos(substr($str, 1, strlen($str-1)), '-') !== false
) {
   echo 'a match';
}