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

JavaScript中使用正则表达式的一点笔记(未完)

阅读更多
前言

前几天在空隙时间在读Mastering Regular Expressions这本书。不愧是关于正则表达式的一本好书,我也应该买一本的。现在是暂时借了阿威买的第三版的中文版来读。中文版翻译得还不错。有不少地方感觉翻译得挺精彩的,虽然马上就能猜到原文是怎么写的,但读起来中文一点都不觉得拗口。

现在才读到第76页,第二章,比较入门的部分。以前也不是没用过正则表达式,不过一边读这书一边就觉得以前真的中了很多陷阱。而且我居然一直不知道正则表达式里面有lookaround(positive/negative lookahead/lookbehind)这种好用的东西……真糟糕。不过现在学到也还不算迟。
比较麻烦的是第二章里几乎全部代码例子都是perl写的,而我以前虽然没少用别人写的perl脚本,自己却几乎没写过perl代码。这下是领略到了不少perl的威力啊。
简单来说,像这样:
$input = <STDIN>; # get a line of input from stdin
chomp( $input );  # cut the trailing newline character

# verify the input as a decimal number
if ( $input =~ /^([-+]?[0-9]+(?:\.[0-9]*)?)$/ ) {
    # verified
    $result = $input * 2;
    print "input multiplied by 2 is: $result";
} else {
    # verification failed
    print "Expecting a number, so I don't understand \"$input\".\n";
}

在我看来就是语言的动态特性与正则表达式的优美结合啊。($input的类型可以自动在String与number之间转换,而正则表达式可以作用在String版本的类型上来检查输入的一行内容里是不是一个合法的数字。)

回头想想,我最初接触正则表达式的时候是在Java上用的。虽然编译原理课上也有讲到DFA/NFA与正则表达式,但那个时候没用在C/C++里用过正则表达式而只是实现过些简单的DFA。
Java里要用正则表达式颇不顺手。最痛苦的莫过于转义字符的问题。那时我对正则表达式里常用的一些预定义字符组之类的很不熟悉,只好阅读Java标准库的JavaDoc来学习。看看java.util.regex.Pattern类的JavaDoc,可以看到很多与转义字符相关的预定义字符组之类的东西,但我当时花了很长时间才理解到Java本身字符串中的转义字符与正则表达式中的转义字符不是一回事——它们是叠加的。为了表达正则表达式里的\b,用Java应该写成"\\b"的字符串;为了匹配一个斜杠和句点“\.”而要写出正则表达式\\\.,在Java中却得写成"\\\\\\."。结果我经常在大量的“\”中迷茫,到底写了多少个“\”都数不清了……

接触到有verbatim string的C#和有Wysiwyg string的D之后这转义的问题减轻了不少,不过要是能直接写正则表达式的字面量而不是用字符串来表示正则表达式就更舒服了。在阅读一些JavaScript的相关文章时留意到有不少人提到“perl风格的正则表达式记法”,查了下,发现这种以operation/regex/modifier为形式的记法确实好用。不过当时也是随便写了几个JavaScript的小测试玩了玩就没管了,也没去看看这记法的来源——perl里它到底长什么样。这次就多记点JavaScript里的perl-style regex吧。

====================================================================

笔记

WebRef上有一套关于JavaScript的教程,不过比较老了,是1997年12月4日最后编辑的。虽然文章比较老了,其中关于正则表达式的部分还是可以参考的;毕竟ECMAScript在v3之后就一直没正式发布更新的版本嘛。JavaScript 1.8要跟随FireFox 3.0才会出现,而JavaScript 2.0得等ECMAScript最终确定。漫长啊。JavaScript 1.8的技巧似乎在这里有些记载,有空的时候要去看看。
等我买了新的犀牛书之后再结合ECMA-262来检查一下有没有些什么更新的地方好了……

Mozilla MDC有对应JavaScript 1.5(带有1.8更新)的正则表达式文档

一些关于lookaround的介绍

先来看点简单的例子吧。
<script>
var str = "<STRONG>text here</STRONG>123"
var regex = /^<([^>]*)>.*<\/\1>(?=\d+)/

// EXAMPLE 1
// validate a string with given regex, returning a boolean value
var result = regex.test(str)
document.write(result + "<BR />") // true

// EXAMPLE 2
// match a string with given regex, returning the matches in an array
result = /(?=\w)(?:[^>]*) (?=\w)/.exec(str)
document.write(result + "<BR />")
// text

for (var i in result) {
    document.write(i + ": " + result[i] + "<BR />")
}
// input: text here123
// index: 8
// lastIndex: 13
// 0: text

// EXAMPLE 3
// match a string with given regex, returning the matches in an array
result = str.match(regex)
for (var i in result) {
    document.write(i + ": " + result[i] + "<BR />")
}
// input: <STRONG>text here</STRONG>123
// index: 0
// lastIndex: 26
// 0: <STRONG>text here</STRONG>
// 1: STRONG

// EXAMPLE 4
// substitute a matched string with some other string
result = "vaarbcaAdbcae".replace(/(a)+(?:.*)(bc)/gi, "_$2-$1_")
document.write(result + "<BR />")
// v_bc-a_ae

// EXAMPLE 5
// substitute a matched string with some other string
result = "vaarbcaAdbcae".replace(/(a)+(?:.*)(bc)/gi, function(str, p1, p2) {
  return "_" + p2 + "+" + p1 + "_"
})
document.write(result + "<BR />")
// v_bc+a_ae
</script>


在关注如何在JavaScript操作正则表达式之前,先看看如何定义一个正则表达式。
与perl一样,JavaScript中可以在一头一尾的两个斜杠(“/”)中间写一个正则表达式的字面量。但具体的状况与perl又不完全相同:
perl:
引用
m/PATTERN/cgimosx
/PATTERN/cgimosx
q/STRING/
'STRING'
qq/STRING/
"STRING"
qr/STRING/imosx
qx/STRING/
`STRING`
qw/STRING/
s/PATTERN/REPLACEMENT/egimosx
tr/SEARCHLIST/REPLACEMENT/cds
y/SEARCHLIST/REPLACEMENTLIST/cds

JavaScript:
引用
/PATTERN/gimy


JavaScript中的正则表达式字面量只能以斜杠开头,而不能像perl里一样在斜杠前指定操作。默认的操作就是m/(match)。在结尾的斜杠后面可以像perl里一样,指定一些修饰符;但不及perl所提供的修饰符号多,只支持以下几种:
g
全局匹配
i
忽略大小写
m
多行匹配
y
FireFox 3/JavaScript 1.8中添加的新修饰符。只从该正则表达式实例的lastIndex属性开始搜索。

在ECMAScript 4的草案中,有提议采纳/x修饰符以支持perl风格的多行正则表达式记法,并允许在正则表达式中使用单行注释来提高可阅读性。不知道最终是否会被采纳呢。

注意:JavaScript的正则表达式中,“.”是不匹配换行符的。要匹配包括换行符在内的所有字符的话可以用“[\s\S]”

当正则表达式的内容需要改变,或需要从用户输入获取等的时候,也可以采用构造器的方式来定义正则表达式:
var regex = new RegExp("pattern" [, "flags"]);

其中代表修饰符的第二个参数是可选的。注意到表示要匹配的模式的第一个参数是用双引号而不是斜杠括起来的。

EXAMPLE 1

这个例子中用到了一个包含了许多特性的正则表达式,与一个字符串进行匹配。
这些特性包括锚,字符组,预定义字符组,量词,捕获型括号,反向引用,环视等。

使用<.*>来匹配标签的话挺容易出问题的,所以这里采用了<[^>]*>来匹配。

EXAMPLE 2

这个例子主要展示了exec()方法的使用。
值得注意的是,JavaScript中只支持顺序环视(lookahead)而不支持逆序环视(lookbehind),所以当需要逆向环视的时候应当想办法将其转换为正向环视。
一段否定正向环视的代码:
js> regex = /\b(?!FX)\b/ig
/\b(?!FX)\b/gi
js> "Fx's not FX".replace(regex, "Alpha")
FxAlpha'AlphasAlpha AlphanotAlpha FXAlpha


EXAMPLE 3

这个例子用EXAMPLE 1里的字符串与正则表达式进行匹配(和捕获),并演示了如何在正则表达式执行过后引用捕获到的匹配。

EXAMPLE 4

这个例子展示了如何使用正则表达式进行替换。

EXAMPLE 4展示了JavaScript中量词的“贪婪”特性——它一定会在整个字符串中找到符合正则表达式要求的最长匹配。更准确的说,是遵循"left-most, longest match"的原则。
在这个例子中,虽然"aarbc"、"aAdbc"与"aarbcaAdbc"都能够匹配,但只有"aarbcaAdbc"才是最长的,因而结果是把整个"aarbcaAdbc"作为匹配,交给替换的逻辑去处理。

EXAMPLE 5

这个例子展示了如何使用正则表达式进行替换,传入一个函数来计算替换的字符串。
传入的函数可能接受的参数为:
str: 整个匹配的子串
p1, p2, ...: 每个捕获分组匹配到的子串
offset: 整个匹配的子串在原字符串中的偏移量
s: 匹配的原字符串

正则表达式相关方法(包括字符串的几个方法)
参考: http://www.webreference.com/js/column5/methods.html

compile
正则表达式的成员方法。compile()方法可以改变一个正则表达式实例的匹配模式及其修饰符。它的参数与RegExp构造器一样。
regex.compile("pattern" [, "flags" ]);


exec
正则表达式的成员方法。exec()的作用某种意义上与perl中的=~运算符相同,都是将一个正则表达式应用在一个字符串上。但是JavaScript中只能定义match功能的正则表达式,所以exec也只能匹配而不能替换。
若存在匹配,调用该方法会更新全局的RegExp对象的属性。
perl:
$str =~ m/PATTERN/;
# - or -
$str =~ s/PATTERN/REPLACEMENT/;
# - and the like -

JavaScript:
var result = regex.exec(str);

调用exec()会返回一个数组,其中包含有下列属性:
input:用于匹配的输入字符串。
index:开始匹配的位置的索引。
lastIndex:最后一次匹配后的最后位置的索引。
0:最后一次匹配的整个字符串内容。
1 ... n:捕获型括号匹配到的字符串内容。
参照上面的EXAMPLE 2的使用方法。

test
正则表达式的成员方法。test()与perl中的=~运算符也可以说相似,用在判断是否存在匹配时。
调用test()会返回一个boolean值来表明是否存在匹配。
调用该方法不会影响全局的RegExp对象的属性。
var existMatch = regex.test(str);


match
字符串的成员方法。match()与正则表达式的exec()作用一样,返回值也一样。
若存在匹配,调用该方法会更新全局的RegExp对象的属性。
var result = str.match(regex);

参见上面的EXAMPLE 3的使用方法。

replace
字符串的成员方法。这个方法是JavaScript中对于perl的s/PATTERN/REPLACEMENT/的对应物。与perl一样,REPLACEMENT里可以有$1、$2...等变量来引用捕获到的匹配。
若存在匹配,调用该方法会更新全局的RegExp对象的属性。
str.replace(regex, replace);

参见上面的EXAMPLE 4的使用方法。

search
字符串的成员方法。这个方法与正则表达式的test()方法一样,用于检验是否存在匹配。
调用该方法不会影响全局的RegExp对象的属性。
var existMatch = str.search(regex);


split
字符串的成员方法。用正则表达式(或普通字符串)指定分隔符,将原字符串分割为多个子串后以数组形式返回。
若存在匹配,调用该方法会更新全局的RegExp对象的属性。
document.write("a string".split(/ */).join(", ")); // a, s, t, r, i, n, g


================================================================

把一个JavaScript里用整数表示、分为单位的值转换为用字符串表示、以元为单位、每三位一组加上逗号分隔的函数:
// 把分转换到元,并在每三位添加一个逗号分隔
function fenToYuan(n) {
  return String(n).replace(/(^\d$)|(^\d{2}$)|(\d{2}$)/, function (_, p1, p2, p3) {
    return p1 && '0.0' + p1 || p2 && '0.' + p2 || p3 && '.' + p3;
  }).replace(/(\d+?)(?=(?:\d{3})+\.\d{2}$)/g, '$1,');
}
分享到:
评论

相关推荐

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

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

    javascript数据校验正则表达式

    本文将深入探讨如何在JavaScript中使用正则表达式进行数据校验。 在JavaScript中,正则表达式主要用于测试一个字符串是否符合特定模式,从而判断其有效性。例如,我们可以使用正则表达式来检查电子邮件地址、电话...

    正则表达式笔记归纳

    它在多种编程语言中都有应用,尤其是在JavaScript中,正则表达式被广泛用于数据验证、文本提取等方面。 #### 二、正则表达式的语法元素 正则表达式由一系列字符和特殊符号组成,用以匹配字符串中的特定模式。下面...

    正则表达式必知必会v_1.0.pdf

    在正则表达式中,可以使用字符集合([xxx])来匹配某些字符中的一个字符。字符集合可以通过显示声明每一个字符,或者通过连字符(-)来指定一个范围的字符。同时,字符集合还可以通过^来声明一个取反的字符集合,即...

    使用正则表达式验证中文汉字输入

    在本主题中,“使用正则表达式验证中文汉字输入”着重讲解如何利用正则表达式来确保用户输入的数据仅包含合法的中文汉字。 首先,我们需要了解中文汉字在计算机中的表示方式。中文字符在Unicode编码中占据着一定的...

    正则表达式学习笔记

    - **JavaScript 正则表达式在线测试工具**:可以在浏览器中实时测试正则表达式的匹配效果。 - **RegexTester**:.Net Framework 下的正则表达式测试工具。 #### 七、总结 正则表达式是处理文本数据的强大工具,...

    传智播客_张孝祥_JavaScript7_正则表达式

    "传智播客_张孝祥_JavaScript7_正则表达式"这个课程可能详细讲解了JavaScript中的正则表达式及其应用。 1. 正则表达式基础: - 定义:正则表达式是一种模式匹配工具,用于描述一种特定的字符串模式。 - 基本元素...

    报表工具FineReport正则表达式定义规则

    在JavaScript中使用正则表达式时,需要在正则表达式前后加上“/”。例如,验证手机号码是否合法的表达式为`/^1(3\d|5[36789])\d{8}$/`。 #### 五、总结 通过以上介绍,我们可以看到正则表达式在报表工具FineReport...

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

    7. 正则表达式在线测试工具:文章中也提供了两个在线测试工具,一个是JavaScript正则表达式在线测试工具,另一个是正则表达式在线生成工具,这两个工具可以帮助开发者测试和生成正则表达式。 8. java正则表达式技巧...

    javascript正则表达式详解

    在JavaScript中进行正则表达式编程时,可以使用多种操作,如验证字符串是否符合某模式、切分字符串、提取匹配的数据以及替换文本。JavaScript提供了正则表达式的API,包括test、exec、search、match、replace等,每...

    JavaScript常用正则表达式

    在JavaScript中,我们可以使用`test()`方法来检查一个字符串是否匹配特定的正则表达式,例如: ```javascript let input = "example@email.com"; if (emailRegex.test(input)) { console.log("Valid email address....

    JavaScript验证正则表达式大全.txtJavaScript验证正则表达式大全.txt

    根据提供的文件信息,本文将详细解释与JavaScript中的正则表达式相关的知识点,这些知识点主要涉及字符串验证、格式检查以及特定模式匹配等方面。 ### 正则表达式基础 在深入探讨具体的正则表达式之前,先简要回顾...

    常用正则表达式大全.txt

    根据提供的文件信息,我们可以整理出一系列与正则表达式相关的...以上内容概括了从文件中提取出来的正则表达式知识点,这些知识点覆盖了正则表达式的多个应用场景,对于从事软件开发、数据分析等领域的人来说非常实用。

    JavaScript手册及正则表达式详解[收藏]

    正则表达式则是JavaScript中的一个重要工具,用于处理字符串的模式匹配和查找。在这个“JavaScript手册及正则表达式详解”中,我们将深入探讨这两个关键主题。 一、JavaScript基础 JavaScript是一种解释型、弱类型...

    js_正则表达式全攻略

    ### 正则表达式在JavaScript中的应用全攻略 #### 一、正则表达式的概念及其在JavaScript中的重要性 正则表达式(Regular Expression)是一种强大的文本处理工具,能够帮助开发者进行复杂的字符串搜索和替换。在...

    boost库中的正则表达式

    在C++编程中,Boost库是一个非常重要的工具集,提供了许多高级功能,其中包括对正则表达式的支持。Boost库中的正则表达式模块提供了一种高效且强大的方式来处理文本模式匹配。本节将深入探讨Boost库中的正则表达式...

    JavaScript正则表达式.ppt

    了解正则表达式概念 掌握正则表达式的语法 熟练掌握正则表达式在JavaScript中的应用

    通过正则表达式生成数据

    在本主题中,我们将深入探讨如何使用正则表达式来生成满足特定条件的随机数据。这在数据测试、生成假数据或者模拟真实场景时非常有用。 一、正则表达式基础 1. **基本元素**:正则表达式由一系列字符和特殊符号...

    JS正则表达式入门笔记实例

    - 正则表达式中使用特殊字符时,需要进行转义,如`\.`表示匹配实际的点号。 - 要注意JavaScript的跨浏览器兼容性问题,某些正则特性可能在某些环境中不可用。 通过实践这些实例,你可以逐步掌握JavaScript中的...

Global site tag (gtag.js) - Google Analytics