`
yiminghe
  • 浏览: 1453147 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

javascript 正则表达式细节问题

阅读更多

以前发过一些文章:

正则表达式的Javascript应用
Extjs 正则表达式的优雅应用 -1


近来再看mastering regular expressions 想到的一些有趣的正则表达式细节问题,首先看

1.一段程序

 

var regs=[/x*/g,/x*$/g,/^x*/g,/^x*$/g,/x*?/g,/^x*?/g,/x*?$/g,/^x*?$/g];
for(var i=0,reg=null;reg=regs[i++];){
 console.log("*************reg :" +reg.source);
 console.log("xx".replace(reg,"y"));
 console.log("xx".match(reg));
var m;
var j=0;

while((m=reg.exec("xx"))&&++j<5){
console.log(m[0]+" - "+reg.lastIndex)
//reg.lastIndex+=1
}
}

 

可以先想一下结果 ,下面为运行输出:

 

*************reg :x*
yy
["xx", ""]
xx - 2
- 2
- 2
- 2
*************reg :x*$
yy
["xx", ""]
xx - 2
- 2
- 2
- 2
*************reg :^x*
y
["xx"]
xx - 2
*************reg :^x*$
y
["xx"]
xx - 2
*************reg :x*?
yxyxy
["", "", ""]
- 0
- 0
- 0
- 0
*************reg :^x*?
yxx
[""]
- 0
- 0
- 0
- 0
*************reg :x*?$
yy
["xx", ""]
xx - 2
- 2
- 2
- 2
*************reg :^x*?$
y
["xx"]
xx - 2

 

 

其中涉及到了:

 

-1. Backtracking(回朔的概念): 对每个量词(quantifier)以及或(||),正则引擎必须做出一个决定,对于量词(*,+,?,{2,}),正则引擎必须决定是否要多匹配一些字符,而对于或(字符类[a-z]或简写\s,.除外)必须决定选择哪个分支。

每次引擎作出了一个选择,它都会记住其他可能的选项,如果这次匹配失败则会退回到上次做选择的量词或位置,并选择其他的选项继续进行匹配。

 

举例:(From High performance javascript)

 

 

0. * 量词可以匹配空,zero match


1.匹配分为位置(开头,字符间,结尾)与字符 两类,match 的所有匹配结果会多一些


2.replace g 时,当遇到空匹配 时在当前位置(开头,字符间,结尾)匹配成功,正则引擎会强行bump-along到下一匹配处 (防止空匹配死循环匹配)


这解释了 /x*?/g 的交替情况


3.为了达到正则表达式整体匹配,后面的表达式会驱动前面的表达式回朔 对于前面为x*


x* 会迫使量词匹配次减 1 ,直到为空匹配则这时一定成功


这解释了 /x*/ ,/x*$/ 一次匹配 xx ,二次到结尾位置空匹配,但是注意  /x*/ 并不包括开头位置^匹配,x*为贪婪匹配,开头位置不能满足,但是bump后,第一个x可以满足,所以无须匹配开头,直接匹配到 xx全部,但是第二次只剩下空字符串,为了匹配成功,才选择了空匹配,可见:

 

"xx".replace(/y*/g,"y")
 


对于前面为 x*?


x*? 会迫使量词增1,直到当前字符不能匹配x位置


这解释了 /x*?$/为了取得 在第一个 x处,为了达到匹配,扩展到 匹配 xx的情况,在第二次空字符串时,就默认0匹配成功了。

 

5.Regexp.lastIndex 为 the position of the first character after the match,但是使用 exec 时遇到结尾空匹配 并不会像 replace一样会强行驱动对*量词连续使用 exec 会造成死循环 ,同java不同,java 连续find遇到结尾空匹配会自动bump的:

 

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
    public static void main(String[] args) throws Exception {
        Pattern p = Pattern.compile("x*");
        Matcher m = p.matcher("xx");
        while (m.find()) {
            System.out.println("match : "+m.group());
        }

        System.out.println("xx".replaceAll("x*","y"));
    }
}

 

2. 多行模式问题: 

 

"1\n\n2\n3".replace(/^.*$/mg,"m"); // m\nm\nm\nm\n
 

^ : 匹配于当前整串头位置,或者 \n 后一个位置,相当于(?<=\n),js不支持

$ : 匹配于整串结尾位置,或者 \n 前一个位置,相当于(?=\n)

. : javascript中不会匹配 \n ,不可设置多行模式,则要匹配到 换行则要手动匹配

若要匹配任何字符则要使用:[\d\D],[\s\S],[\w\W],[\0-\uffff] 以及(?:.|\r|\n|\u2028|\u2029) 尽量用 character class少用 alteration


行缩减应用:

 

"1\n\n2\n3".replace(/^.*$\n?/mg,"m"); //mmmm
 

 

2010-09-20 update :


备忘,强大的 jquery 正则式整理报告

 

 

 

  • 大小: 24.4 KB
1
0
分享到:
评论
1 楼 xiongzhijian51 2010-01-20  
难得楼主能沉下心来钻研,真的佩服你.

相关推荐

    精通正则表达式中文版英文版_中文版为扫描版

    书中的例子涵盖了多种编程语言,如Perl、Java、JavaScript、.NET等,这些语言的正则表达式引擎虽然大同小异,但在细节上有所区别,学习者将了解到如何在不同环境下应用正则表达式。 对于初学者,书中会引导他们理解...

    正则表达式基础正则表达式基础

    不同的编程语言或工具可能采用不同的正则表达式引擎,如Perl兼容正则表达式(PCRE)、JavaScript的正则表达式等,它们在语法细节和功能上可能存在差异。 五、进阶技巧 1. 非贪婪匹配:默认情况下,量词是贪婪的,会...

    [精通正则表达式(第三版)].(美)佛瑞德.扫描版(modify).pdf

    在编程中,大多数编程语言如Python、Java、JavaScript等都内置了对正则表达式的支持。通过正则表达式,可以对文本进行复杂的匹配、提取、分割和替换操作。 由于本书在标题和描述中未提供具体的内容细节,无法就具体...

    正则表达式经典实例

    《正则表达式经典实例》这本书深入浅出地介绍了正则表达式的基本概念和高级特性,并提供了丰富的实例,覆盖了C#、Java、JavaScript、Perl、PHP、Python、Ruby和VB.NET等多种编程语言。 #### 二、核心内容概览 1. *...

    正则表达式素材5

    通过这个文件,读者可以深入理解正则表达式的各个细节,并通过实例来加深印象。 “正则表达式解释器实现原理”这部分内容则深入到正则表达式引擎的工作机制。正则表达式解释器是处理正则表达式的软件组件,它将人类...

    正则表达式教材资料合集

    10. **正则表达式引擎**:不同的编程语言或工具可能使用不同的正则表达式引擎,如Perl兼容正则表达式(PCRE)和JavaScript的正则引擎,它们在某些细节上可能存在差异。 通过深入学习本资料合集中的教材,你将能够...

    精通正则表达式(第3版).pdf

    由于正则表达式涉及到很多细节,编写一本书来全面介绍它是一项浩大的工程。精通正则表达式第3版这类书籍会详细地介绍这些内容,并且随着版本的更新,书中的内容也会不断更新以适应新的技术标准和最佳实践。本书不仅...

    正则表达式匹配(自动转换)

    在描述中提到的"无需再为正则表达式而烦恼",意味着这样的工具或功能提供了便捷的方式,使得用户在处理复杂的文本模式时,不再需要深入了解正则表达式的细节,只需提供合适的表达式,系统就能自动完成匹配工作。...

    正则表达式工具.zip

    此外,正则表达式工具可能还支持多种正则表达式引擎的语法,如Perl、JavaScript、Python等,因为它们在某些细节上略有不同。例如,JavaScript的`/g`修饰符用于全局匹配,而Python中的`re.findall()`函数可以获取所有...

    正则表达式从入门到精通正则表达式从入门到精通

    正则表达式通常在编程语言中配合函数使用,如 Python 的 `re` 模块,JavaScript 的 `match()`、`search()`、`replace()` 等方法。在数据处理时,可以利用正则表达式进行高效的数据清洗和提取,比如从日志文件中提取...

    eclipse正则表达式插件regex util

    Eclipse是一款广受欢迎的开源集成开发环境(IDE),它为Java开发者提供了强大的代码编辑、调试和项目管理功能。...通过Regex Util插件,开发者可以将更多精力集中在解决问题上,而不是在正则表达式的细节上浪费时间。

    精通正则表达式_第三版(英文版)

    最后,书中会讨论如何在各种编程语言中使用正则表达式,包括Perl、Java、JavaScript、Python和Ruby等。每种语言都有其特有的API和实现细节,理解这些差异对于实际开发至关重要。 总之,《精通正则表达式》第三版是...

    正则表达式中文帮助文档.rar

    这个“正则表达式中文帮助文档”应该包含了正则表达式的详细解释、实例演示以及常见问题解答,可以帮助学习者更好地理解和运用正则表达式。通过阅读文档,你将能够了解更多的细节,比如如何在不同环境下使用正则,...

    javascript正则表达式总结.docx

    JavaScript正则表达式是编程语言JavaScript中用于处理文本模式匹配的重要工具。正则表达式(Regular Expression)是一种模式,用于匹配字符串中的一段或多段文本。以下是对JavaScript正则表达式的一些关键知识点的...

    正则表达式验证表单

    ### 正则表达式验证表单 在网页开发与数据处理中,正则表达式是一种非常重要的工具,它被广泛应用于各种验证逻辑中,比如表单验证...在实际应用中,还可以根据具体需求调整正则表达式的细节,以满足更复杂的验证场景。

    正则表达式详解大全珍藏版

    正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、搜索和替换等场景。在这个“正则表达式详解大全珍藏版”中,我们将深入探讨如何使用正则表达式来校验各种...

    javascript正则表达式之分组概念与用法实例.docx

    ### JavaScript正则表达式之分组概念与用法 #### 分组的概念 在JavaScript中,正则表达式是一种强大的文本处理工具,它可以帮助我们完成复杂的字符串搜索和替换操作。正则表达式的分组是一个非常重要的概念,通过...

    正则表达式验证工具

    例如,JavaScript、Python、Java等语言虽然都支持正则表达式,但具体的语法和功能细节可能有所不同。 总之,正则表达式验证工具是提升正则表达式使用体验的重要辅助工具,它们帮助我们更好地理解和调试正则表达式,...

    常用各类验证 正则表达式

    在实际开发中,可以根据具体需求调整这些正则表达式的细节,以满足更加复杂的验证需求。同时,也可以结合前端JavaScript和后端语言(如Java、Python等)进行更加高效的数据校验工作。正则表达式是数据验证的重要工具...

Global site tag (gtag.js) - Google Analytics