正则表达式匹配问题?


本模块提供了与 Perl 语言类似的正则表达式匹配操作。

模式和被搜索的字符串既可以是 Unicode 字符串 () ,也可以是8位字节串 ()。 但是,Unicode 字符串与 8 位字节串不能混用:也就是说,不能用字节串模式匹配 Unicode 字符串,反之亦然;同理,替换操作时,替换字符串的类型也必须与所用的模式和搜索字符串的类型一致。

正则表达式用反斜杠字符 ('\') 表示特殊形式,或是允许在使用特殊字符时,不引发它们的特殊含义。 这与 Python 的字符串字面值中对相同字符出于相同目的的用法产生冲突;例如,要匹配一个反斜杠字面值,用户可能必须写成 '\\\\' 来作为模式字符串,因为正则表达式必须为 \\,而每个反斜杠在普通 Python 字符串字面值中又必须表示为 \\。 而且还要注意,在 Python 的字符串字面值中使用的反斜杠如果有任何无效的转义序列,现在会触发 ,但以后会改为 。 此行为即使对于正则表达式来说有效的转义字符同样会发生。

解决办法是对于正则表达式模式(patterns)使用 Python 的原始字符串表示法;在带有 'r' 前缀的字符串字面值中,反斜杠不必做任何特殊处理。 因此 r"\n" 表示包含 '\''n' 两个字符的字符串,而 "\n" 则表示只包含一个换行符的字符串。 模式在 Python 代码中通常都使用原始字符串表示法。

绝大多数正则表达式操作都提供为模块函数和方法,在 . 这些函数是一个捷径,不需要先编译正则对象,但是损失了一些优化参数。

第三方模块 , 提供了与标准库 模块兼容的 API 接口,同时,还提供了更多功能和更全面的 Unicode 支持。

正则表达式(或 RE)指定了一组与之匹配的字符串;模块内的函数可以检查某个字符串是否与给定的正则表达式匹配(或者正则表达式是否匹配到字符串,这两种说法含义相同)。

正则表达式可以拼接;如果 AB 都是正则表达式,则 AB 也是正则表达式。通常,如果字符串 p 匹配 A,并且另一个字符串 q 匹配 B,那么 pq 可以匹配 AB。除非 A 或者 B 包含低优先级操作,AB 存在边界条件;或者命名组引用。所以,复杂表达式可以很容易的从这里描述的简单源语表达式构建。更多正则表达式理论和实现,详见 the Friedl book ,或者其他构建编译器的书籍。

以下是正则表达式格式的简要说明。更详细的信息和演示,参考 。

正则表达式可以包含普通或者特殊字符。绝大部分普通字符,比如 'A', 'a', 或者 '0',都是最简单的正则表达式。它们就匹配自身。你可以拼接普通字符,所以 last 匹配字符串 'last'. (在这一节的其他部分,我们将用 this special style 这种方式表示正则表达式,通常不带引号,要匹配的字符串用 'in

有些字符,比如 '|' 或者 '(',属于特殊字符。 特殊字符既可以表示它的普通含义, 也可以影响它旁边的正则表达式的解释。

重复修饰符 (*, +, ?, {m,n}, 等) 不能直接嵌套。这样避免了非贪婪后缀 ? 修饰符,和其他实现中的修饰符产生的多义性。要应用一个内层重复嵌套,可以使用括号。 比如,表达式 (?:a{6})* 匹配6个 'a' 字符重复任意次数。

(点) 在默认模式,匹配除了换行的任意字符。如果指定了标签 ,它将匹配包括换行符的任意字符。

(插入符号) 匹配字符串的开头, 并且在 模式也匹配换行后的首个符号。

匹配字符串尾或者在字符串尾的换行符的前一个字符,在 模式下也会匹配换行符之前的文本。 foo 匹配 'foo' 和 'foobar',但正则表达式

group 默认为0,就是整个匹配。

pos 的值,会传递给 或 的方法 a 。这个是正则引擎开始在字符串搜索一个匹配的索引位置。

endpos 的值,会传递给 或 的方法 a 。这个是正则引擎停止在字符串搜索一个匹配的索引位置。

捕获组的最后一个匹配的整数索引值,或者 None 如果没有匹配产生的话。比如,对于字符串 'ab',表达式 (a)b, ((a)(b)), 和

最后一个匹配的命名组名字,或者 None 如果没有产生匹配的话。

返回产生这个实例的 , 这个实例是由 正则对象的 或 方法产生的。

传递到 或 的字符串。

在这个例子里,我们使用以下辅助函数来更好地显示匹配对象:

要看给定的字符串是否有效,我们可以按照以下步骤

最后一手牌,"727ak" ,包含了一个对子,或者两张同样数值的牌。要用正则表达式匹配它,应该使用向后引用如下

要找出对子由什么牌组成,开发者可以按照下面的方式来使用匹配对象的 方法:

Python 目前没有一个类似c函数 scanf() 的替代品。正则表达式通常比 scanf() 格式字符串要更强大一些,但也带来更多复杂性。下面的表格提供了 scanf() 格式符和正则表达式大致相同的映射。

从文件名和数字提取字符串

将字符串用参数传递的样式分隔开。这个方法对于转换文本数据到易读而且容易修改的数据结构,是很有用的,如下面的例子证明。

首先,这里是输入。 它通常来自一个文件,这里我们使用三重引号字符串语法

条目用一个或者多个换行符分开。现在我们将字符串转换为一个列表,每个非空行都有一个条目:

最终,将每个条目分割为一个由名字、姓氏、电话号码和地址组成的列表。我们为 使用了 maxsplit 形参,因为地址中包含有被我们作为分割模式的空格符:

:? 样式匹配姓后面的冒号,因此它不出现在结果列表中。如果 maxsplit 设置为 4 ,我们还可以从地址中获取到房间号:

替换字符串中出现的样式的每一个实例。这个例子证明了使用 来整理文字,或者随机化每个字符的位置,除了首位和末尾字符

匹配样式 所有 的出现,不仅是像 中的第一个匹配。比如,如果一个作者希望找到文字中的所有副词,他可能会按照以下方法用

查找所有的副词及其位置

如果需要匹配样式的更多信息, 可以起到作用,它提供了 作为返回值,而不是字符串。继续上面的例子,如果一个作者希望找到所有副词和它的位置,可以按照下面方法使用

原始字符串记法 (r"text") 保持正则表达式正常。否则,每个正则式里的反斜杠('\') 都必须前缀一个反斜杠来转义。比如,下面两行代码功能就是完全一致的

当需要匹配一个字符反斜杠,它必须在正则表达式中转义。在原始字符串记法,就是 r"\\"。否则就必须用 "\\\\",来表示同样的意思

一个 分析字符串,并分类成目录组。 这是写一个编译器或解释器的第一步。

文字目录是由正则表达式指定的。这个技术是通过将这些样式合并为一个主正则式,并且循环匹配来实现的

该词法器产生以下的输出

在了解正则表达式之前,我们先看几个非常常见的问题:

  • 如何判断字符串是否是有效的电话号码?例如:010-1234567123ABC456,等;

  • 如何判断字符串是否是有效的电子邮件地址?例如:,test#example等;

  • 如何判断字符串是否是有效的时间?例如:12:3409:6099:99等。

一种直观的想法是通过程序判断,这种方法需要为每种用例创建规则,然后用代码实现。下面是判断手机号的代码:

上述代码仅仅做了非常粗略的判断,并未考虑首位数字不能为0等更详细的情况。

除了判断手机号,我们还需要判断电子邮件地址、电话、邮编等等:

为每一种判断逻辑编写代码实在是太繁琐了。有没有更简单的方法?

正则表达式可以用字符串来描述规则,并用来匹配字符串。例如,判断手机号,我们用正则表达式\d{11}

使用正则表达式的好处有哪些?一个正则表达式就是一个描述规则的字符串,所以,只需要编写正确的规则,我们就可以让正则表达式引擎去判断目标字符串是否符合规则。

正则表达式是一套标准,它可以用于任何语言。Java标准库的java.util.regex包内置了正则表达式引擎,在Java程序中使用正则表达式非常简单。

举个例子:要判断用户输入的年份是否是20##年,我们先写出规则如下:

一共有4个字符,分别是:200~9任意数字0~9任意数字

对应的正则表达式就是:20\d\d,其中\d表示任意一个数字。

把正则表达式转换为Java字符串就变成了20\\d\\d,注意Java字符串用\\表示\

最后,用正则表达式匹配一个字符串的代码如下:

可见,使用正则表达式,不必编写复杂的代码来判断,只需给出一个字符串表达的正则规则即可。

正则表达式是用字符串描述的一个匹配规则,使用正则表达式可以快速判断给定的字符串是否符合匹配规则。Java标准库java.util.regex内建了正则表达式引擎。

我要回帖

更多关于 js正则表达式匹配字符串 的文章

 

随机推荐