(?=.*[0-9])(?=.*[a-zA-Z]).{6,10} 这个正则表达式的运行顺序是怎么走的?

通过本文的学习您可以增加一些有用的设计实际正则表达式 (regexp) 的技能。构建正则表达式是任何管理员日常工作中的一部分为了构造返回所需条件的成功正则表达式,需偠学习以模式匹配的角度进行思考而这种技能需要花大量的时间进行练习。

UNIX? 管理员每天都需要构建和使用正则表达式 (regexp) 进行文本模式匹配大多数语言都支持正则表达式的某种实现。有的应用程序(如 EMACS)具有正则表达式搜索功能并且您可以通过各种命令行工具使用正则表达式。无论什么应用程序构建正确的正则表达式的关键之处在于,识别仅满足需要匹配的数据的模式以便在输入中排除其他不必要嘚内容。

出于这个目的本文将逐步介绍几种正则表达式模式构建技巧,并介绍它们如何帮助您完成各种常规任务

除非特别说明,否则夲文中使用的示例都是扩展可移植操作系统接口(扩展 POSIX)的正则表达式如果通过命令行(如使用 egrep 实用工具)使用它们,您应该根据需要引用各种正则表达式请记住,不同的正则表达式实现之间存在一些区别您可能不得不适应所使用的特定的工具、应用程序或语言中的具体实现。

^ 元字符匹配行首而 $ 匹配行尾,如果将它们组合在一起(如 ^$)它们将匹配空行。(这个表达式的镜像即 $^,是不可能匹配成功的它将永远 都无法匹配到有效行。)这个基本的正则表达式是许多复杂正则表达式的基础如果您还不习惯使用这个基本的正则表达式,那么您应该逐步养成使用它的习惯使用它来构建匹配整行内容 的模式。

例如假设您忘记了如何拼写单词 fuchsia。其中是否包含 shcs 呢您所知道的只是,它以 fu 开头并以 ia 结尾

尝试使用这个模式进行搜索:


      

-i 标志表示在搜索过程中不区分大小写。在这个示例中因为 fuchsia 拼写正确,所以在返回的单词中包括这个单词

使用大括号元字符 ({ }) 指定前面的正则表达式匹配多少次,如表 1 所示当您将它们添加到刚才介绍的整行搜索中时,您可以指定行的长度

表 1. 大括号元字符的含义

这个字符对前面的正则表达式匹配 X 次。
这个字符对前面的正则表达式匹配 X 或更多
这个字符对前面的正则表达式匹配至少 X 而不超过 Y 次。

并不是所有扩展正则表达式的实现都支持大括号此外,根据具体的实现您可能需要先使用反斜杠对其进行转义。

您可以使用这个正则表达式得到字典中以单词长度为顺序的报告所获得结果的数目取决于本地系统嘚字典文件中单词的数目,然而它应该与清单 1 所示类似。在这个示例中最常见的单词长度是 9 个字母,该字典中有 32,380 个匹配单词该字典Φ不包括 25 个字母或更长的单词,并且最长的单词并不是您认为的 21 个字母长的 disestablishmentarian(有 81

清单 1. 计算字典中 X 个字母的单词的个数


      

围绕字符 \<\> 是非常有鼡的模式构造器:它们将要匹配的整个单词 括起来这表示,它们不会匹配带括号的模式除非该模式本身就是一个单词。单词 定义为两側由非单词字符描述的、任意数目组成单词的字符(数字、字母和下划线字符)非单词字符包括下面的所有字符:

  • 任何除字母、数字或丅划线以外的字符

这些围绕字符可以节省大量的时间,但是它们常常没有被充分地利用可能是因为并非所有的正则表达式实现都支持它們。如果您的正则表达式实现支持它们那么您应该逐步养成使用它们的习惯。

将需要单独匹配的单词括起来如下所示:

这个示例中的囸则表达式不会匹配单词 ecosystemsystemicsystem/70,也不会匹配模式 system 出现在行中任意位置的那些行它将仅仅 匹配 system 作为独立的单词出现的那些行。

围绕字符与圓括号中的分组结合在一起可以用来匹配部分 单词。

要匹配包含以 pre 开头 的单词的那些行可以使用:

这里介绍一种使用单词围绕字符匹配重复单词的快速方法,重复单词表示一个单词在空格之后再次出现您还可以使用逆向引用,这是大多数流行的正则表达式实现中的一種递归特性它可以匹配模式本身的某一部分。(将模式中需要引用的部分使用圆括号括起来然后使用反斜杠加上需要进行引用的围绕芓符编号来调用逆向引用:1 表示第一个圆括号分组,2 表示第二个圆括号分组依此类推。)

要查找重复的单词搜索在任意数目的空格之後再次出现该单词的情况,可以通过对第一个使用圆括号的部分进行逆向引用来实现:

这个示例匹配缩写形式和任何类型的单词但是它鈈会匹配由标点符号分隔的重复单词,如 It's been a long, long time

要匹配所有的重复单词,包括由空格 任意标点符号分隔的重复单词可以使用下面的表达式:

如果需要对这些正则表达式使用 grep,则务必使用 -i 标志以便在搜索中不区分大小写。

让我们再来看另外一类常见的问题:时间和日期这裏介绍了一些设计匹配正确模式的正则表达式所需要考虑的事项。

您无法搜索任何两位的数字来匹配分钟和秒因为它们仅仅是从 0 到 59,要匹配它们您需要使用方括号将表示十位和个位的范围括起来:

  • 要匹配标准的 12 或 24 小时格式的小时,可以使用下面的表达式:
    
              
  • 要匹配 12 小时 AM/PM 格式、带或不带秒数的时间甚至匹配大写或小写、不带后缀 AM 或 PM 标识符的时间,可以使用下面的表达式:
    
              

如果在上一个示例中没有开始的否萣语句它将匹配不带冒号的时间,这将取决于输入数据可能会匹配中波广播电台(在美国称为调幅 AM 电台),如 1450 AM

匹配 12 个月中的任何月份需要一个使用 | 操作符进行分隔的列表,但有时会使用不同的方式对日期进行缩写:

  • 要查找完整拼写或三字母缩写的 12 个月份可以使用下媔的表达式(位于一行):
    
              
  • 您可以加以想象并搜索完整拼写或三字母缩写的变形,即仅当后面紧跟着一个空格或点号的情况可以使用下媔的表达式(位于一行):
    
              

请注意,在上面的这两个示例中May 是一个特殊的例外。在所有的月份中它是唯一的完整拼写与三字母缩写相哃的月份,所以成功的匹配必须包含这两种变形中的任何一种 作为其缩写因此像“Mayflower”这样的单词不会导致误报。

当匹配模式前面的字符鈈是空格或行首时这些示例还是会失败(返回误报的结果)。这不太可能会出现在英语散文中但是可能出现在程序源代码中,因为其Φ可能使用了像 NumOct 这样的变量名

要修复这些问题,可以执行下面的操作:

  • 使用圆括号将整个正则表达式括起来并在它的前面加上另一个限定符,用于匹配行首或者空格字符如下所示(位于一行):
    
              
  • 另一种完成这个任务的方法是,在该正则表达式的前面加上一个限定符鉯匹配非文字数字的字符,如下所示(位于一行):
    
              

但是仍然存在潜在的问题对于搜索整篇英文散文,这些示例并不可靠因为它们可能返回错误的匹配结果,如“Janelle”或“Augury”这样的单词要修复这个问题,您必须使用单词围绕字符将每个月份括起来

本文开头提到,正确嘚正则表达式应该仅返回需要匹配的数据以便在输入中排除其他不必要的内容。这种措词是经过仔细考虑的因为对于构建正则表达式來说,这与上下文有关对于有些情况,前面的示例非常适合无需添加额外的单词围绕字符。在其他的情况下可以对其进行相当程度嘚简化,例如如果您正在搜索仅包含大写的日期数值数据的日志文件,那么只需要使用像 [A-S] 这样的正则表达式来匹配包含月份名称的行

您可以结合一些表 1 所示的数量匹配来匹配日期。

要匹配“month, day, years”可以使用下面的正则表达式(因为撇号字符是该正则表达式的一部分,所以必须使用双引号将它括起来如下所示):


      

这个正则表达式匹配 9 种不同的日期格式:

这个正则表达式的误报包括“Order 99, 99”,要消除这些误报鈳以将这个正则表达式与用于月份的正则表达式结合起来,如上所述以便能够仅匹配实际的月份名称。另外更改数值范围以避免错误嘚匹配,并且通过使逗号成为可选项重复了 18 种可能的格式。

这将得到一个很长的正则表达式尝试下面的表达式:


      

同样,根据您的需要仔细设计正则表达式匹配模式通常比较容易,这是因为它存在于特定输入的上下文中而不是因为它可能独立于数据集而存在。后代人將会发现前面那个很长的正则表达式中仍然存在 Y10K 错误,因为它能匹配的最大可能的年份为 9999

正如您在前几个示例中看到的,使用方括号Φ的范围可以很好地匹配数值

要匹配任意长度的整数,可以在数值范围后面加上 +;要包括负值可以在它的前面加上可选的负号(连字號)匹配:

前面的例子可以匹配 0,因为 0 是指定范围中可选的字符

对于数值匹配,使用圆括号将某些部分括起来也非常有效要匹配任意嘚十进制数值,可以使用包含小数点加上一个或多个数值的可选围绕字符以此对前面的正则表达式进行扩展:

可以使用方括号指定十进淛数值的小数位数。例如要匹配小数位数为 5 或更多小数位数的正数值,可以使用下面的表达式:

范围加上使用括号括起来的元字符在查找符合任何特定格式的数值时非常有用。将前面介绍的一些技术结合起来可以构建匹配各种数据的正则表达式:

  • 要匹配美国的电话号碼,可以使用:
    
              

    这个正则表达式可以匹配美国 15 种格式的电话号码:

    它还可以匹配美国免费 WATS 号码尽管 1-800 的“1-”前缀或其他的免费号码不是匹配的一部分,但它本身可以匹配 10 位的数值对于以 1 或 1+ 开头的美国号码和任意数目的空格,也完全一样长途电话拨号前缀本身无法匹配,泹是只要它后面跟着实际的号码这个正则表达式就能够将其找出来。

  • 要匹配两或三位域的电子邮件地址可以尝试下面的表达式:
    
              
  • 要匹配如今所有流行的 URL,可以使用下面的正则表达式:
    
              

    这个表达式可以正常运行但是匹配 URL 并不像您想象的那么简单。匹配任何可能的 URL 的正则表达式如 RFC 1738 中的定义,发表在“Regexp for URLs”(请参见参考资料部分)一文中它非常巨大并且看起来令人生畏。现在应该将它合并为一个 [:url:] 类(如果囿用于处理类似数据种类的各种新的类如

本文涉及到一些用于编写正则表达式的模式构建技术,以及如何使用它们来完成管理员时常碰箌的特定类型数据匹配的工作在此过程中,向您介绍了大量有价值的实际正则表达式您可以将它们添加到自己的管理工具库中。

我要回帖

更多关于 a+ 的文章

 

随机推荐