5.6.3.6 字符串的模式匹配方法

  String类型定义了几个用于在字符串中匹配模式的方法。第一个方法就是macth(),在字符串上调用这个方法,本质上与调用RegExp()的exec()方法相同。match()方法只接收一个参数,要么是一个正则表达式,要么是一个RegExp()对象。例如:

var text="cat,bat,sat,fat";
var pattern=/.at/;

//与pattern.exec(text)相同
var matches=text.match(pattern);
alert(matches.index);//0
alert(matches[0]);//"cat"
alert(pattern.lastIndex); //0

  这个例子的match()方法  了一个数组;如果是调用RegExp对象的exec()方法并传递本例中的字符串作为参数,那么也会得到与此同时的数组:数组的第一项是是与整个模式匹配的字符串,之后的每一项(如果有)保存着与正则表达式中的捕获组 匹配的字符串。

  另一个用于查找模式的方法是search()。这个方法的唯一参数与match()方法的参数相同:由字符串或RegExp对象指定的一个正则表达式。search()方法返回字符串中的第一个匹配项的索引;如果没有找到匹配项,则返回-1。而且,search()方法始终是从字符串开头向后查找模式。例如:

var text="cat,bat,sat,fat";
var pos=text.search(/at/);
alert(pos);//1

  这个例子中的search()方法返回1,即“at”在字符串中第一次出现的位置。

  为了简化替换子字符串的操作,ECMAScript提供了replace()方法。这个方法接收两个参数:第一个参数可以是一个RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是字符串或者一个函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有的字符串,就需要提供一个正则表达式,而且要指定全局(g)标志,例如:

var text="cat,bat,sat,fat";
var result=text.replace("at","ond");
alert(result);//"cond,bat,sat,fat"

result=text.replace(/at/g,"ond");
alert(result);//"cond,bond,sond,fond"

  在这例子中,首先出入replace()方法的是字符串“at”和需要替换成的字符串“ond”。替换的结果是把“cat”替换成了“cond”,但字符串中的其他字符并没有影响。然后,通过将第一个参数修改为带有全局标志的正则表达式,就将字符串中全部带有“at”的字符替换成了“ond”。

  如果第二个参数是字符串,那么还可以使用一些特殊字符序列,将正则表达式操作得到的值插入到结果中去。下表列出了ECMAScript提供的这些特殊字符序列。

字符序列 替换文本
$$ $
$& 匹配整个模式的字符串。与RegExp.lastMatch的值相同。
$‘ 匹配的子字符串之前的子字符串。与RegExp.leftContext值相同。
$` 匹配的子字符串之后的子字符串。与RegExp.rightContext值相同。
$n
匹配第n个捕获的子字符串,其中n等于0~9。例如,$1是匹配第一个捕获组的子字符串,$2是匹配第二个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串

$nn
匹配第nn个捕获组的子字符串,其中nn等于01~99。例如,$01是匹配第一个捕获组的子字符串,$02是匹配第二个捕获组的子字符串,以此类推。如果正则表达式中没有定义捕获组,则使用空字符串。

  

  通过这些特殊的字符序列,可以使用最近一次匹配结果中的类容,例如:

var text="cat,sat,bat,fat";
result=text.replace(/(.at)/g,"word($1)");
alert(result);//word(cat),word(sat),word(bat),word(fat)

  在此,每个以“at”结尾的单词都被替换了,替换结果是以“word”后跟一对圆括号,而括号中是被字符序列$1所替换的单词。

  replace()方法的第二个参数也可以是个函数。在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3个参数:模式匹配项,模式匹配项在字符串中的位置和原始字符串。在正则表达式中定义了多个捕获组的情况下,传递给函数的参数依次是模式的匹配项、第一个捕获组的匹配项、第二个捕获组的匹配项......,但是最后两个参数仍然分别是模式的匹配项在字符串中位置和原始字符串。这个函数应该返回一个字符串,表示应该被替换的匹配项。使用函数作为replace()方法的第二个参数可以实现更加精细的替换操作,例如:

function htmlEscape(text)
{
    return text.replace(/[<>"&]/g, function(match,pos,originalText)
    {
        switch(match)
        {
            case "<": return "&lt;";

            case ">": return "&gt;";

            case "&": return "&amp;";

            case "\": return "&quot";
        }
    });
}

alert(htmlEscape("<p class=\"greeting\">Hello world !</p>")); //&lt;p class=&quot;greeting&quot;&gt;Hello world !&lt;/p&gt;

  这里,我们为插入HTML代码定义了函数htmlEscape(),这个函数能够转义4个字符:小于符号、大于符号、和号以及双引号。实现这种转义的最简单方式,就是使用正则表达式查找者几个字符,然后定义一个能针对每个匹配的字符返回特定的HTML实体的函数。

  最后一个与模式匹配有关的方法是split(),这个方法可以基于指定的分隔符将一字符串分割成多个字符串,并将结果放在一个数组中。分隔符可以是字符串,也可以是一个RegExp对象(这个方法不会将字符串看成正则表达式)。split()方法可以接受可选的第二个参数,用于指定数组的大小,以便于确保返回的数组不会超过既定大小。离去:

var colorText="red,blue,green,yellow";
var colors1=colorText.split(",");//["red","blue","green","yellow"]
var colors2=colorText.split(",",2);//["red","blue"]
var colors3=colorText.split(/[^\,]+/);//["",",",",",",",""]

  在上例子中,colorText是逗号分隔的颜色字符串。基于该字符串调用了split(",")会得到一个包含其中颜色名的数组,用于分隔字符串的分隔符是逗号。为了将数组截短,让它只包含两项,可以为split()方法传递第二个参数2。最后通过使用正则表达式,还可以取得包含逗号字符的数组。需要注意的是,在最后一次调用split()返回的数组中,第一项和最后一项是两个空字符串。之所以会这样,是因为通过正则表达式指定的分隔符出现了字符串的开头(即子字符串“red”)和末尾(即子字符串“yellow”)。

  对split()中正则表达式的支持因浏览器而异。尽管对于简单的模式没有什么差别,但对于未发现匹配项以及带有捕获组的模式,匹配的行为就不大相同了。以下是几种常见的差别:

  • IE8 以及之前版本会忽略捕获组。ECAM-262规定应该把捕获组拼接到结果数组中。IE9能正确的在结果中包含捕获组。
  • FF3.6以及之前的版本在捕获组未找到匹配项时,会在结果数组中包含空字符串;ECAM-262规定没有匹配项的捕获组在结果数组中应该用undefined表示。

  在正则表达式中使用捕获组时还有其他微妙的差别。在使用这种正则表达式时,一定要在各种浏览器下多做一些测试。

时间: 2024-08-28 05:13:28

5.6.3.6 字符串的模式匹配方法的相关文章

JavaScript string字符串对象常见方法

本文总结下几种常见的字符串方法 一.字符方法 chartAt()与charCodeAt() 1.1 chartAt()以单字符字符串的形式返回给定位置的那个字符 1.2 charCodeAt()返回的是字符编码. var str="hello world" //chartAt()以单字符字符串的形式返回给定位置的那个字符 console.log(str.charAt(4));//o //charCodeAt()返回的是字符编码. console.log(str.charCodeAt(4

lua中的字符串操作(模式匹配)

模式匹配函数 在string库中功能最强大的函数是: string.find(字符串查找)string.gsub(全局字符串替换)string.gfind(全局字符串查找)string.gmatch(返回查找到字符串的迭代器) 这些函数都是基于模式匹配的.与其他脚本语言不同的是,Lua并不使用POSIX规范的正则表达式[4](也写作regexp)来进行模式匹配.主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比整个Lua标准库加在一起都大

字符串的模式匹配中的算法

字符串的模式匹配是一个比较经典的问题:假设有一个字符串S,称其为主串,然后还有一个字符串T,称其为子串. 现在要做的是,从主串S当中查找子串T的位置,如果存在返回位置值,如果不存在返回-1.另外主串又称为目标串, 子串称为模式串. 暴力匹配算法 这是一个经典的串匹配问题,涉及的算法也比较多,先讨论第一种简单的暴力算法,思路如下 将主串S的第pos个字符 与 子串T的第一个字符比较, 若相同,继续比较子串和主串后面的字符. 若不相同,那么从主串S的第(pos + 1)个字符开始继续向后匹配,直到匹

7.python字符串-内置方法分析

上篇对python中的字符串进行了列举和简单说明,但这些方法太多,逐一背下效率实在太低,下面我来对这些方法安装其功能进行总结: 1.字母大小写相关(中文无效) 1.1 S.upper() -> string 返回一个字母全部大写的副本 1.2 S.lower() -> string 返回一个字母全是小写的副本 1.3 S.swapcase() -> string 返回一个字母大小写转换后的副本 1.4 S.title() -> string 将单词的首字母大写,即为所谓的标题 方框

JS总结之一:字符串的调用方法

字符串的调用方法:var s="hello, world";document.write(s.charAt(0)); //第一个字符document.write(s.charAt(s.length-1)); //最后一个字符document.write(s.substring(1,4)); //第2~4个字符document.write(s.slice(-3)); //最后3个字符document.write(s.indexOf("l")); //字符l首次出现的位

Oracle字符串连接的方法

Oracle数据库中,使用“||”进行字符串连接,下面就让我们一起了解一下Oracle数据库中字符串连接的方法,希望对您能有所帮助. 和其他数据库系统类似,Oracle字符串连接使用“||”进行字符串拼接,其使用方式和MSSQLServer中的加号“+”一样. 比如执行下面的SQL语句:SELECT '工号为'||FNumber||'的员工姓名为'||FName FROM T_EmployeeWHERE FName IS NOT NULL 除了“||”,Oracle还支持使用CONCAT()函数

深入.Net字符串类型 Join方法

.Net的字符串其实还是有很多东西可以写的.但是最近在学习SQL Server,只好先做下最近学习到的一些巧用,妙用之类的东西. 巧用String.Join拼接字串数组,字符串集合为字符串.如果在之前,一个foreach早就敲上去了.虽然效率差多,但是少了个foreach,还是美观不少的. class Program { static void Main(string[] args) { List<string> listStr = new List<string>(); list

Python 字符串分割的方法

在平时工作的时候,发现对于字符串分割的方法用的比较多,下面对分割字符串方法进行总结一下:第一种:split()函数split()函数应该说是分割字符串使用最多的函数用法:str.split('分割符')通过该分割操作后,会返回一个列表. 注:当然如果你的字符串含有一个或者多个空格就直接 str.split() 就可以了 例如: >>> a = "hello,python,Good Night" >>> a.split(',') ['hello', '

【转】三种常用的字符串判空串方法

1. 三种常用的字符串判空串方法:Length法:bool isEmpty = (str.Length == 0);Empty法:bool isEmpty = (str == String.Empty);General法:bool isEmpty = (str == ""); 2. 深入内部机制:要探讨这三种方法的内部机制,我们得首先看看.NET是怎样实现的,也就是要看看.NET的源代码!然而,我们哪里找这些源代码呢?我们同样有三种方法:Rotor法:一个不错的选择就是微软的Rotor