FANG KE (Coor)

Always Seeking an Adventure.

说说正则表达式

Thu 16 February 2017

Regular Expression

正则表达式,英文为Regular Expression。它有点类似于C语言中的条件运算符(conditional operator)? :

例如: max = (a>b)?a:b ,若条件符合,则max被赋予值a,反之则b。

但虽然类似,这两者可完全不是一个概念。真正的正则表达式是能够使用单个字符串来描述、匹配某种特定句法规则的字符串。它常常被用于文本编辑器中,以便于用户查找和替换某种特定模式的文本。更准确的说,在编程语言中,它主要用于“操作字符串”。

Why

我的这个问题源自于今日在编写PHP代码时,需要检测用户输入的用户名是否合法。所设想的规则是:该用户名可以由字母、数字、汉字、下划线和减号组成,不能以数字开头,长度为6-24个字符,如输入内容全部为中文,则范围是3-12个(考虑一个中文字符占位两个英文字符)。这时如果想实现用户输入字符串的检测,则必须使用到正则表达式。

接下来就把我写成的方法跟大家分析一下:

publicfunctionis_username($username){
    $length= (strlen($username)+mb_strlen($username,'utf8'))/2;
  if(!preg_match("/^\b[a-zA-Z\x{4e00}-\x{9fa5}][a-zA-Z0-9_\-\x{4e00}-\x{9fa5}]{1,}$/u", $username)){
    #echo"输入不合法<br>";
    $error= "含有特殊字符";
    return$error;

  }elseif($length<6 || $length>24) {
      #echo"当前长度: ".$length."<br>";
      #echo"长度不合法<br>";
      $error= "长度不合法";
    return$error;

  }else{
      $error= "";
    return$error;
  }
}

Explanation

该方法用于检测输入字符串是否符合规则,如果符合构成规则和长度规则,则返回错误为空,如果不合法,则返回相应的错误信息。这里字符串的长度通过分别用strlen()mb_strlen()函数测量,然后将结果求和后除2,这么做的主要原因是在strlen函数中,utf-8编码规则的中文字符被当做3个英文字符,也就是说strlen("一个")该函数的返回值为6。而一般我们所使用的2个英文字符等价为1个汉字字符,该规则主要是针对使用了GBK2312编码方式,而现在UTF-8的编码方式已经普遍应用,为了不打破原有的计数规则,方便用户,这里首先使用strlen计算中英文共有多少个字符,此时的一个字母为1个字符,一个汉字为3个字符,而稍后我们使用mb_strlen()函数再次测量,这里请注意使用该函数的时候,第二个参数是以UTF-8的编码规则来计算,这样的话不论是中文还是英文,一个字母和一个汉字都被当做1个字符,也就是说strlen("一个", 'utf8')该函数的返回值为2。这样的话我们将两次的结果相加后,相当于1个汉字被计算成为了4个字符,一个字母被计算成为了2个字符,刚好是标准规则的2倍,所以除以2后得到经典意义上的“字符串长度”。

Conclusion

上面的关于字符串长度的计算方式的讨论算是题外话。这里我们回来看正则表达式。在正则表达式中, ^符号被用来标记字符串的开始位置,$符号被用来标记结束位置,其间的内容为匹配规则。由于正则表达式的内容非常之多,这里只解释本表达式的含义,其余的跟多关于正则表达式的用法,可以参考下表。在本文所涉及的规则中,^符号后首先出现的是\b,该转义字符标记了这里应该是一个单词的边界,由于该输入字符串的预设规则中不允许空格,所以可以将该字符串理解为一个很长的单词,标记出了单词的开始,也是说我们接下来想要匹配的规则就是输入字符串只能以数字、字母或者汉字为开头,那么在后面方括号中的内容即要求匹配字母a-z,A-Z,字符_,字符-,和以UTF8编码的汉字(不含符号)范围\x{4e00}-\x{9fa5},这样就完成了首字母的匹配。接下来匹配剩余部分,剩余部分不需要标记开始位置,所以直接标记范围[a-zA-Z0-9_\-\x{4e00}-\x{9fa5}],该范围比第一个范围多了数字0-9,在该范围的标记后标记匹配次数,{1,}的意思是至少要匹配一次,至多匹配到字符串结束。这样我们就完成了字符串规则的制定,然后通过调用PHP内部函数preg_ match()来执行匹配操作,如果匹配则返回值为真,反之则假。至此关于如何使用正则表达式判断输入是否正确就完成了。

更多关于正则表达式的使用方法,可以参考正则表达式的维基百科:

正则表达式