`

使用正则表达式

    博客分类:
  • php
阅读更多
原作者:Mitchell Harper  翻译:iwind
原文:http://www.devarticles.com/c/a/P ... lar-Expressions-101

一个正则表达式是一个特定的格式化模式,可以用来找出一个字符串在另一个字符串中的使用情况。几个编程语言,包括Visual Basic,Perl,JavaScript和PHP都支持正则表达式,希望在这篇入门指导的结束,Mitchell(作者自己)可以让你在PHP程序中能应用一些基本的正则表达式。正则表达式是在各种各样的程序语言中突出的古怪特征中的一种,但是由于它们看起来是很难的一个概念,所以很多开发者就把它们放到了角落里,忘记了它们的存在。
让我们先来看看什么是正则表达式,为什么你要在PHP程序中用到它们。

什么是正则表达式?

你对从一个不错的老的基于控制的文本编辑器中分离出像BBEdit和notepad的程序,有什么看法呢?两个都支持文本输入,可以让你保存文本到文件中,但是现在的文本编辑器也支持其它功能,包括查找–代替工具,这让编辑一个文本文件相当容易。
     正则表达式也是相似的,只是更好一些。正则表达式可以被认为一个极其高级的查找-替换工具,让我们从痛苦中摆脱出来:不必再写定制的数据确认例子来检查电子邮件地址或者来确认电话号码的格式是正确的,如此等等。
     任何程序中最普通的函数之一就是数据有效性检查,PHP捆绑了一些文本检查函数,允许我们用正则表达式匹配一个字符串,确认有一个空格,有一个问号,等等。
     你不知道的可能是,正则表达式可以简单装备吗,当你掌握了一些正则表达式时(这个正则表达式可以用来告诉正则表达式引擎一个字符串中我们想要匹配的部分),你会自问为什么会把正则表达式扔到角落里这么久,^_^。
     PHP有两套函数,用来处理两种类型的正则表达式: Perl5兼容模式,和Posix标准兼容模式。在这篇文章中我们将看看ereg函数,用遵照Posix标准的搜索表达式工作。虽然它们并没有Perl5模式那样强大,但是一种不错的学习正则表达式的方法。如果你对PHP支持的Perl5兼容正则表达式感兴趣,可以到PHP.net网站找一些关于preg函数的细节。
     PHP有六个函数来处理正则表达式,它们都把一个正则表达式作为它们的第一个参数,列出如下:

ereg: 最常用的正则表达式函数, ereg 允许我们搜索跟一个正则表达式匹配的一个字符串.
ereg_replace: 允许我们搜索跟正则表达式匹配的一个字符串,并用新的字符串代替所有这个表达式出现的地方。
eregi: 和ereg几乎是一样效果,不过忽略大小写。
eregi_replace: 和ereg_replace有着一样的搜索-替换功能,不过忽略大小写.
split: 允许我们搜索和正则表达式匹配的字符串,并且以字符串集合的方式返回匹配结果.
spliti: split函数忽略大小写的版本.
为什么使用正则表达式?

       如果你不断地建立不同的函数来检查或者操作字符串的一部分,现在你可能要放弃所有的这些函数,取而代之的用正则表达式。如果你对下列的问题都答“是的”,那么你肯定要考虑使用正则表达式了:

你是否正在写一些定制的函数来检查表单数据(比如在电子信箱地址中的一个@,一个点)?
你是否写一些定制的函数,在一个字符串中循环每个字符,如果这个字符匹配了一个特定特征(比如它是大写的,或者它是一个空格),那么就替换它?
      除了是令人不舒服的字符串检查和操作方法,如果没有有效率地写代码,上述的两条也会使你的程序慢下来。你是否更倾向于用下面的代码检查一个电子信箱地址呢:

<?php
function validateEmail($email)
{
      $hasAtSymbol = strpos($email, "@");
      $hasDot = strpos($email, ".");
      if($hasAtSymbol && $hasDot)
         return true;
      else
         return false;
}
echo validateEmail("mitchell@devarticles.com");
?>
... 或者使用下面的代码:

<?php
function validateEmail($email)
{
    return ereg("^[a-zA-Z]+@[a-zA-Z]+.[a-zA-Z]+$", $email);
}
echo validateEmail("mitchell@devarticles.com");
?>

    可以肯定的是,第一个函数比较容易,而且看起来结构也不错。但是如果我们用上面的下一个版本的email地址检查函数不是更容易吗?

    上面展示的第二个函数只用了正则表达式,包括了对ereg函数的一个调用。Ereg 函数返回true或者false,来声明它的字符串参数是否和正则表达式相匹配。

很多编程者避开正则表达式,只因为它们(在一些情况下)比其它的文本处理方法更慢。正则表达式可能慢的原因是因为它们涉及把字符串在内存中拷贝和粘贴,因为正则表达式的每一个新的部分都对应匹配一个字符串。但是,从我对正则表达式的经验来说,除非你在文本中几百个行运行一个复杂的正则表达式,否则性能上的缺陷都可以忽略不计,当把正则表达式作为输入数据检查工具时,也很少出现这种情况。





正则表达式语法
在你可以匹配一个字符串到正则表达式之前,你必须先建立正则表达式。开始的时候,正则表达式的语法有点古怪,表达式中的每一个短语代表某个类型的搜索特征。下列是一些最普通的正则表达式,也都对应着一个如何使用它的例子:

字符串头部
搜索一个字符串的头部,用^,例如

<?php echo ereg("^hello", "hello world!"); ?>
将返回 true, 但是
<?php echo ereg("^hello", "i say hello world"); ?>
将返回 false, 因为hello不在字符串”I say hello world”的头部。
字符串尾部

搜索字符串尾部,用$,例如:
<?php echo ereg("bye$", "goodbye"); ?>
将返回true, 但是
<?php echo ereg("bye$", "goodbye my friend"); ?>
将返回 false,因为bye不在字符串”goodbye my friend”的尾部.

任意的单个字符
搜索任意字符,用点(.),例如:
<?php echo ereg(".", "cat"); ?>
将返回true,但是
<?php echo ereg(".", ""); ?>
将返回false,因为我们的要搜索字符串没有包含字符。你可以用花括号随意告诉正则表达式引擎它要匹配多少个单个字符。如果我只想匹配5个字符,我可以这样用ereg:
<?php echo ereg(".{5}$", "12345"); ?>
上面的这段代码告诉正则表达式引擎当且仅当至少5个连续的字符出现字符串的尾部时返回true.我们也可以限制连续出现的字符的数目:
<?php echo ereg("a{1,3}$", "aaa"); ?>
在上面的例子里,我们已经告诉正则表达式引擎,我们的搜索字符串来匹配表达式,它在尾部必须有介于1和3个的”a”字符。
<?php echo ereg("a{1,3}$", "aaab"); ?>
上面的例子将不会返回true,虽然有三个”a”字符在搜索字符串里,但是它们不是在字符串的尾部。如果我们把结尾字符串匹配$从正则表达式中去掉,那么这个字符串是匹配的。
我们也可以告诉正则表达式引擎来匹配至少有确定数目的字符在一行,如果它们存在的,可以匹配更多。 我们可以这样做:
<?php echo ereg("a{3,}$", "aaaa"); ?>

零或多次重复字符
为了告诉正则表达式引擎一个字符可能存在,也可以重复,我们用*字符。这里的两个例子都将返回true.

<?php echo ereg("t*", "tom"); ?>
<?php echo ereg("t*", "fom"); ?>
即使第二个例子不包含”t”这个字符,但仍旧返回ture,因为*表示字符可以出现,但不是必须出现。事实上,任何普通的字符串模式都会使上面的ereg调用返回true,因为’t’字符是可选的.


一或多次重复字符
为了告诉正则表达式引擎一个字符必须存在,也可以重复不止一次,我们用+字符,像

<?php echo ereg("z+", "i like the zoo"); ?>
下面的例子也会返回true:
<?php echo ereg("z+", "i like the zzzzzzoo!"); ?>

零或一次重复字符
我们也可以告诉正则表达式引擎,一个字符必须是或者只存在一次,或者没有。我们用?字符来做这项工作,就像
<?php echo ereg("c?", "cats are fuzzy"); ?>
如果我们愿意,我们完全可以从上面的搜索字符串中删除’c’,这个表达式会仍旧返回true.’?’ 的意思是一个’c’可以出现在搜索字符串的任何地方,但不是必须的。



正则表达式语法 (续)
空格字符
为了匹配一个搜索字符串中的空格字符,我们用预定义Posix的类,[[:space]].方括号标明连续字符的相关性,”:space:”是实际要匹配的类(在这种情形下,是任何空白字符)。空白包括tab字符,新行字符,空白字符。或者,如果搜索字符串必须包含只有一个空格,而不是一个tab或者新行字符,你可以用一个空格字符(" ")。在大多数情况下,我倾向于使用":space:",因为这意味着我的意图不仅仅是单个空格字符,这点很容易被忽视。这里有一些Posix-标准预定义类,
有一些我们可以作为正则表达式的部分的一些Posix-标准预定义类,包括[:alnum:], [:digit:], [:lower:]等等。 完整的列表可以在这里查看

我们可以像这样匹配单个空白字符:

<?php echo ereg("Mitchell[[:space:]]Harper", "Mitchell Harper"); ?>
我们也可以通过在表达式后用?字符来告诉正则表达式引擎匹配没有空白或者一个空白。
<?php echo ereg("Mitchell[[:space:]]?Harper", "MitchellHarper"); ?>

模式分组
相关的模式可以在方括号里分在一起。很容易用[a-z]和[A-Z]指定只有一个小写字母或者一列大写字母以搜索字符串的一部分存在。
<?php
// 要求从第一个到最后一个都是小写字母
echo ereg("^[a-z]+$", "johndoe"); // 返回true
?>
或者像
<?php
// 要求从第一个到最后一个都是大写字母
ereg("^[A-Z]+$", "JOHNDOE"); // 返回 true?
?>
我们也可以告诉正则表达式引擎,我们希望或者是小写字母,或者是大写字母。我们只要把[a-z]和[A-Z]模式结合在一起就可以做到。
<?php echo ereg("^[a-zA-Z]+$", "JohnDoe"); ?>
在上面的例子里,如果我们能匹配"John Doe",而不是"JohnDoe",将是非常有意义的。我们用下面的正则表达式来做这个:
^[a-zA-Z]+[[:space:]]{1}[a-zA-Z]+$
很容易搜索一个数字字符串
<?php echo ereg("^[0-9]+$", "12345"); ?>

词语分组
不仅仅搜索模式可以分组,我们也可以用圆括号把相关的搜索词语进行分组。
<?php echo ereg("^(John|Jane).+$", "John Doe"); ?>
在上面的例子中,我们有一个字符串头部字符,紧跟着"John"或者"Jane",至少有一个其它字符,然后一个字符串尾部字符。所以…
<?php echo ereg("^(John|Jane).+$", "Jane Doe"); ?>
...将也匹配我们的搜索模式

特殊字符的情形
因为一些字符要用在一个搜索模式的明确分组或者语法上,像在(John|Jane)中的圆括号,我们需要告诉正则表达式引擎来屏蔽这些字符,加工它们使之成为被搜索字符串的一部分,而不是搜索表达式的一部分。我们所用的方法称为“字符转义”,涉及到将任何“专用符号”加上反斜杠。所以,例如,如果我想在我的搜索中包含’|’,那么我就可以这样做
<?php echo ereg("^[a-zA-z]+|[a-zA-z]+$", "John|Jane"); ?>
这里只是少量的一些你要转义的字符,你必须转义^, $, (, ), ., [, |, *, ?, +, and { 。
希望你现在对正则表达式实际上有多么强大有了一点点感觉了。现在让我们看两个用正则表达式来检查数据中一个字符串的例子。



正则表达式例子
例子1
让我们把第一个例子做的相当简单,检验一个标准的URL.一个标准的URL(没有端口号),有三个部分构成:

[协议]://[域名]

让我们从匹配URL的协议部分开始,并且让它只能用http或者ftp.我们可以用下面的正则表达式做到这点:

^(http|ftp)
^字符特指字符串的头部,利用圆括号把http和ftp围住,且用“或者”符号(|)将它们分开,我们告诉正则表达式引擎http和ftp两者之一必须在字符串的开头。

一个域名通常由www.somesite.com构成,但是可以随意选择要不要www部分。为了例子简单,我们只允许.com,.net,和.org的域名是在考虑之中的。我们最好这样对正则表达式中的域名部分表示如下:
(www.)?.+.(com|net|org)$
把所有的东西放在一起,我们的正则表达式就可以用作检查一个域名,如:

<?php
function isValidDomain($domainName)
{

return ereg("^(http|ftp)://(www.)?.+.(com|net|org)$", $domainName);
}
//真(true)
echo isValidDomain("http://www.somesite.com");
//真(true)
echo isValidDomain("ftp://somesite.com");
//假 (false)
echo isValidDomain("ftp://www.somesite.fr");
//假 (false)
echo isValidDomain("www.somesite.com");
?>

例子二
因为我居住在澳大利亚悉尼,让我们检查一个典型的澳大利亚国际电话号码。澳大利亚国际电话号码的格式如下:
+61x xxxx-xxxx
第一个x是区号,其它的都是电话号码。检查以'+61'开头且紧跟一个在2到9之间的区号的电话号码,我们用下面的正则表达式:

^+61[2-9][[:space:]]
注意,上面的搜索模式把'+'字符用''转义,以便于可以在搜索中包含,不至于被解释为一个正则表达式。[2-9]告诉正则表达式引擎我们需要包含一个2到9之间的数字。[[:space:]]类则告诉正则表达式期望在这里有一个空白。


这里是电话号码剩下的搜索模式:
[0-9]{4}-[0-9]{4}$
这里没有什么不寻常的地方,我们只是告诉正则表达式引擎电话号码可用的数字,它必须是4个数字的组合,跟着一个连接符,再跟着另一个4个数字的组合,然后一个字符串尾部字符。
把完整的正则表达式放在一起,放进一个函数,我们可以用代码来检查一些澳大利亚国际电话号码:
<?php
function isValidPhone($phoneNum)
{
echo ereg("^+61[2-9][[:space:]][0-9]{4}-[0-9]{4}$", $phoneNum);
}
// 真(true)
echo isValidPhone("+619 0000-0000");
// 假(false)
echo isValidPhone("+61 00000000");
//假( false)
echo isValidPhone("+611 00000000");
?>



总结
正则表达式用一些不适合书写和重复的代码来检查一个字符串。在最后的几页里,我们已经讲解了所有的Posix标准正则表达式的基础,包括字符,分组和PHP ereg函数。我们也知道了怎么用正则表达式来检查一些PHP中简单的字符串。
分享到:
评论

相关推荐

    pb 使用正则表达式源码pbregexp

    标题中的“pb 使用正则表达式源码pbregexp”指的是在PowerBuilder(简称pb)环境中,利用名为“pbregexp”的正则表达式组件来实现源代码级别的正则表达式操作。PowerBuilder是一款流行的可视化的、面向对象的软件...

    Java使用正则表达式提取XML节点内容的方法示例

    Java使用正则表达式提取XML节点内容的方法示例 Java使用正则表达式提取XML节点内容的方法示例主要介绍了Java使用正则表达式提取XML节点内容的方法,结合具体实例形式分析了java针对xml格式字符串的正则匹配相关操作...

    java使用正则表达式判断手机号的方法示例

    java使用正则表达式判断手机号的方法示例文章主要介绍了java使用正则表达式判断手机号的方法,分析了手机号码段的原理及java使用正则表达式针对手机号的匹配操作实现技巧。下面是文章中提到的知识点: 1. 手机号码...

    PB实现的正则表达式

    在本话题中,我们将探讨如何使用PowerBuilder 11.5这一经典的开发环境来实现正则表达式功能。PowerBuilder是一款基于对象的快速应用程序开发工具,尤其适合于数据库应用系统的开发。 标题"PB实现的正则表达式"表明...

    使用正则表达式验证一年的12个月份

    在实际应用中,通常会结合编程语言来使用这些正则表达式。例如,在JavaScript中,你可以用`test()`函数来验证输入: ```javascript const regex = /^(0?[1-9]|1[0-2])$/; // 或者更复杂的版本 const input = "05"; ...

    在C语言中使用正则表达式

    在C语言中使用正则表达式可以为程序增添强大的文本处理能力。正则表达式是一种模式匹配工具,常用于搜索、替换和提取文本中的特定模式。C语言标准库提供了`&lt;regex.h&gt;`头文件,支持基本的正则表达式操作。然而,与...

    qt使用正则表达式限制lineEdit的输入,对正则表达式进行了封装,可以直接引入,工程编译正常

    在Qt中,我们可以使用`QRegularExpression`类来处理正则表达式。这个类提供了构造、匹配和替换等方法,使我们在C++代码中操作正则表达式变得简单。 接下来,我们探讨如何在lineEdit中应用正则表达式。Qt的lineEdit...

    Python3如何优雅地使用正则表达式.pdf

    在实际使用时,通常需要根据具体问题设计正则表达式模式,编写正则表达式需要一定的经验积累和对正则表达式语法的熟练掌握。例如,如果我们需要匹配一个电子邮件地址,可能需要构建一个复杂的正则表达式来包含用户名...

    正则表达式在数据库查询中的应用

    - **兼容性问题**:不同的数据库系统支持的正则表达式语法可能存在差异,需要根据所使用的数据库类型调整正则表达式的写法。 - **安全性问题**:在用户输入的数据中使用正则表达式时,应注意防止SQL注入攻击,确保...

    正则表达式转换工具

    - 数据验证:在表单提交时,可以使用正则表达式验证输入格式,如邮箱、电话号码等。 - 文件搜索:在代码编辑器中,使用正则表达式快速查找和替换特定模式的文本。 - 数据清洗:在数据预处理阶段,正则表达式可以...

    C#计算器-使用正则表达式解决

    在本项目中,我们主要探讨如何使用C#编程语言创建一个计算器,并且通过正则表达式来处理输入的计算表达式。正则表达式是一种强大的文本处理工具,它能够匹配、查找、替换以及验证字符串模式。在计算器应用中,我们...

    Java 使用正则表达式对象实现正则的获取功能

    在 Java 中,使用正则表达式对象可以实现各种字符串匹配和提取操作。正则表达式对象主要通过 Pattern 和 Matcher 两个类来实现。下面详细介绍如何使用正则表达式对象实现正则获取功能。 一、基本概念 在使用正则...

    Linux在合集中使用正则表达式来匹配查找.zip

    综上所述,这个压缩包文件合集详细地介绍了Linux环境中如何使用正则表达式进行文本匹配和处理,涵盖了正则表达式的基础知识、sed工具的使用以及grep系列命令的应用。掌握这些内容,将极大地提高你在Linux系统中处理...

    delphi下使用正则表达式控件集

    本篇文章将详细探讨在Delphi下使用正则表达式的控件集,以及如何利用它们来增强你的应用程序功能。 标题提及的“delphi下使用正则表达式控件集”主要包括两个组件包:RegExpr和DEELX。这两个组件库为Delphi开发者...

    C语言正则表达式库

    1. **语法兼容性**:如描述所述,PCRE库的正则表达式语法与Perl语言高度兼容,这意味着开发者可以利用Perl中广泛使用的正则表达式语法,如贪婪和非贪婪量词、分支选择、反向引用等。 2. **Unicode支持**:PCRE库...

    VC、VC++,MFC 正则表达式类库

    在标准C++库中,虽然没有内置的正则表达式支持,但通过包含如 Boost 或 TR1(Technical Report 1)扩展,或者在较新的C++11及更高版本中使用库,开发者可以实现正则表达式功能。然而,对于MFC开发者来说,使用MFC内...

    python使用正则表达式提取网页URL的方法

    本文实例讲述了python使用正则表达式提取网页URL的方法。分享给大家供大家参考。具体实现方法如下: import re import urllib url=//www.jb51.net s=urllib.urlopen(url).read() ss=s.replace( ,) urls=re.findall...

    UE中使用正则表达式的一些技巧

    UE中使用正则表达式

    C#使用正则表达式验证IP地址

    使用正则表达式来判断用户输入的IP地址格式是否正确

Global site tag (gtag.js) - Google Analytics