JavaScript 正则表达式

本文详细介绍了正则表达式的基本概念、创建方法、字符类、量词、选择与分组、匹配位置、修饰符及其在JavaScript中的应用,包括search、replace、match、split方法的使用。

正则表达式本身就是一种语言,这在其它语言是通用的。

正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。

创建正则对象

要使用正则表达式,必须要在程序创建正则对象 。我们需要得到一个RegExp类的实例。

① 直接量语法创建(隐式创建)

正则表达式直接量定义为包含在一对斜杠(/)之间的字符。

var reg = /匹配模式/匹配标志;

② 构造函数创建

通过 RegExp() 构造函数可以实现动态创建正则表达式。RegExp() 的第二个参数是可选的。

var reg = new RegExp( " 匹配模式 " , ' 匹配标志 ' );

 

正则表达式字符

直接量字符

正则表达式中所有字母和数字都是按照字面含义进行匹配的,其他非字母的字符需要通过反斜杠(\)作为前缀进行转移,如 \n 匹配换行符。这些字符为直接量字符(literal characters)。这些字符都是精确匹配,每一个字符都只能匹配一个字符。

在正则表达式中,有一些标点符号具有特殊含义,他们是:^ $ . * + ? = ! : | \ / ( ) [ ] { } 如果需要在正则表达式中与这些直接量进行匹配,必须使用前缀 \ 。

 

字符类

如果不想匹配某一个特定的字符而是想匹配某一类字符,则需要使用字符类。

通过将直接量字符放入方括号内,可以组成字符类(character class)。一个字符类可以匹配它所包含任意 一个 字符。如 [abc] 可以匹配 a,b,c 中任意一个字符。

使用 ^ 作为方括号中第一个字符来定义否定字符集,它匹配所有不包含在方框括号内的字符。[^] 可以匹配任意字符。

字符类可以使用连字符来表示字符范围。比如匹配小写字母[a-z],匹配任何字母和数字可以用[a-zA-Z0-9]。

 

转义字符

一些常用的字符类,在 JavaScript 中有特殊的转义字符来表达它们。

字符匹配
 [...]方括号内任意字符,方括号用于查找某个范围内的字符
 [^...]不在方括号内任意字符,方括号用于查找某个范围内的字符
.除了换行符和其他 Unicode 行终止符之外的任意字符
\w等价于 [a-zA-Z0-9_]
\W等价于 [^a-zA-Z0-9_]
\s任何 Unicode 空白符
\S任何非 Unicode 空白符的字符
\d等价于 [0-9]
\D等价于 [^0-9]
\b匹配单词边界。通常用于查找位于单词的开头或结尾的匹配。
\B匹配非单词边界。匹配位置的上一个和下一个字符的类型是相同的:即必须同时是单词,或必须同时是非单词字符。字符串的开头和结尾处被视为非单词字符。
\0查找 NULL 字符。
\n查找换行符。
\f查找换页符。
\r查找回车符。
\t查找制表符。
\v查找垂直制表符。

例如:

[abc]查找方括号之间的任何字符。
[^abc]查找任何不在方括号之间的字符。
[0-9]查找任何从 0 至 9 的数字。
[a-z]查找任何从小写 a 到小写 z 的字符。
[A-Z]查找任何从大写 A 到大写 Z 的字符。

var str = "Runoob Runoob"; 
var patt1 = /\bRun/g;

document.write(str.replace(patt1,"AAA"));

结果为:AAAoob AAAoob
var str = "Rnoob Runoob"; 
var patt1 = /\Bnoob/;
document.write(str.replace(patt1,"AAA"));
结果为:RAAA Runoob

量词

字符含义
n{X,Y}

X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。

例如:/a{1,3}/  匹配 "candy," 中的 "a","caandy," 中的两个 "a",匹配 "caaaaaaandy" 中的前面三个 "a"。

n{X,}

X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。

例如:/a{2,} 匹配 "caandy" 和 "caaaaaaandy." 中所有的 "a"。

n{X}

匹配包含 X 个 n 的序列的字符串。

例如:/a{2}/  匹配 "caandy," 中的两个 "a",且匹配 "caaandy." 中的前两个 "a"。

n?

匹配任何包含零个或一个 n 的字符串。

例如,/e?le?/ 匹配 "angel" 中的 "el","angle" 中的 "le"。

n+

匹配任何包含至少一个 n 的字符串。

例如,/a+/ 匹配 "candy" 中的 "a","caaaaaaandy" 中所有的 "a"。

n*

匹配任何包含零个或多个 n 的字符串。

例如,/bo*/ 匹配 "A ghost booooed" 中的 "boooo","A bird warbled" 中的 "b",但是不匹配 "A goat grunted"。

n$

匹配任何结尾为 n 的字符串。

例如,var str="Is this his"; var patt1=/is$/g; 

^n

匹配任何开头为 n 的字符串。

例如,var str="Is this his"; var patt1=/^Is/g; 

?=n

匹配任何其后紧接指定字符串 n 的字符串。

例如,对其后紧跟 "all" 的 "is" 进行全局搜索:var str="Is this all there is";var patt1=/is(?= all)/g;

?!n匹配任何其后没有紧接指定字符串 n 的字符串。var str="Is this all there is";var patt1=/is(?! all)/gi;

 

贪婪和非贪婪的重复

上面所有的重复都是“贪婪的”匹配,也就是匹配尽可能多的字符。如 /a+/ 匹配 'aaaa' 时,它会匹配 'aaaa' 。

如果想要尽可能少的匹配,只需要在重复的标记后加一个问号(?)即可。如 /a+?/ 匹配 'aaaa' 时,它会匹配 'a' 。

 

选择、分组和引用

选择
字符 | 用于分隔供选择的模式,匹配时会尝试从左到右匹配每一个分组,直到发现匹配项。如 /ab|bc|cd/ 可以匹配字符串'ab'、'bc' 和 'cd'。

// 一个分组中,可以有多个候选表达式,用|分隔:
var reg = /I love (him|her|it)/;
reg.test('I love him')  // true
reg.test('I love her')  // true

捕获型分组
圆括号可以把单独的项组合成子表达式,以便可以像一个独立的单元用 |、*、+ 或者 ? 对单元内的项进行处理。

// 这里reg中的(/d{2})就表示一个分组,匹配两位数字。
var reg = /(\d{2})/

// 引用:被正则表达式匹配(捕获)到的字符串会被暂存起来。其中,由分组捕获的串会从1开始编
// 号,于是我们可以引用这些串,$1引用了第一个被捕获的串,$2是第二个,依次类推。分组可以通过$0-$9引
// 用,其中的$0只的是匹配的整个结果。比如我们想将日期12.21/2012改为2012-12-21:
var reg = /(\d{2}).(\d{2})\/(\d{4})/
var date = '12.21/2012'
date = date.replace(reg, '$3-$1-$2') // date = 2012-12-21

// 反向引用
// 正则表达式里也能进行引用,这称为反向引用:
var reg = /(\w{3}) is \1/
reg.test('kid is kid') // true
reg.test('kid is dik') // false
// \1引用了第一个被分组所捕获的串,换言之,表达式是动态决定的。

 非捕获型分组

有时候,我们只是想分个组,而没有捕获的需求,则可以使用非捕获型分组,语法为左括号后紧跟" ?: "

// 正向前瞻型分组:
var reg = /kid is a (?=doubi)/
reg.test('kid is a doubi') // true  // kid is a 后面跟着什么?如果是doubi才能匹配成功。
reg.test('kid is a shabi') // false

// 负向前瞻型分组:
var reg = /kid is a (?!doubi)/
reg.test('kid is a doubi') // false
reg.test('kid is a shabi') // true  // 负向前瞻则刚好相反,不是doubi才能匹配成功。

 

指定匹配位置(锚元素)

有一些正则表达式的元素不用来匹配实际的字符,而是匹配指定的位置。我们称这些元素为正则表达式的锚。

正则表达式中的锚字符包括:

  • ^ 用来匹配字符串的开始,多行检索时匹配一行的开头。
  • $ 用来匹配字符串的结束,多行检索时匹配一行的结尾。
  • \b 用来匹配单词的边界,就是 \w 和 \W 之间的位置,或者 \w 和字符串的开头或结尾之间的位置。
  • \B 匹配非单词边界的位置。
  • 例: /\bJava\b/ 可以匹配 Java 却不匹配 JavaScript。

任意正则表达式都可以作为锚点条件。

先行断言
(?=pattern) 它表示一个位置,该位置之后的字符能匹配 pattern 。如 /\d+(?=%)/ 匹配字符串 '100%' 中的 '100' 但是不匹配 '100。'

负向先行断言
(?!pattern) 它表示一个位置,该位置之后的字符不能匹配 pattern 。

后行断言
(?<=pattern) 它表示一个位置,该位置之前的字符能匹配 pattern 。例,/(?<=\$)\d+/ 匹配 '$100' 但是不匹配 '¥100'。

负向后行断言
(?<!pattern) 它表示一个位置,该位置之前的字符能不匹配 pattern。

 

修饰符

在正则表达式的第二条斜线之后,可以指定一个或多个修饰符,/pattern/g。

常用修饰符:

  • i 执行不区分大小写的匹配。
  • g 全局匹配。
  • m 多行匹配模式。
  • y “粘连”(sticky)修饰符。y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。
  • s 表示点(.)可以表示任意字符,不设置的话,四个字节的 UTF-16 字符和行终止符不能用 . 表示。
  • u 开启 “Unicode 模式”,用来正确处理大于 \uFFFF 的 Unicode 字符。也就是说,会正确处理四个字节的 UTF-16 编码。

通过 RegExp.prototype.flags 可以获得正则修饰符的字符串。/pattern/ig.flags 返回 "gi"。

 

JavaScript search() 方法

定义和用法

search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。

如果没有找到任何匹配的子串,则返回 -1。

语法

string.search(searchvalue)

参数值

参数描述
searchvalue必须。查找的字符串或者正则表达式。

返回值

类型描述
Number与指定查找的字符串或者正则表达式相匹配的 String 对象起始位置。

例如 

var str="Visit Runoob!"; 
var n=str.search("Runoob"); //6

 

JavaScript replace() 方法

定义和用法

replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

语法

string.replace(searchvalue,newvalue)

参数值

参数描述
searchvalue必须。规定子字符串或要替换的模式的 RegExp 对象。
请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。
newvalue必需。一个字符串值。规定了替换文本或生成替换文本的函数。

返回值

类型描述
String一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的。

 例如 

var str="Visit Microsoft! Visit Microsoft!";
var n=str.replace("Microsoft","Runoob"); //Visit Runoob!Visit Microsoft!

 

JavaScript match() 方法

定义和用法

match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。

 语法

string.match(regexp)

参数值

参数描述
regexp必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象。

返回值

类型描述
Array存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。 如果没找到匹配结果返回 null 。

例如

var str="The rain in SPAIN stays mainly in the plain"; 
var n=str.match(/ain/g); //ain,ain,ain

 

JavaScript split() 方法

定义和用法

split() 方法用于把一个字符串分割成字符串数组。

提示: 如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。

注意: split() 方法不改变原始字符串。

语法

string.split(separator,limit)

参数值

参数描述
separator可选。字符串或正则表达式,从该参数指定的地方分割 string Object。
limit可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。

返回值

类型描述
Array一个字符串数组。该数组是通过在 separator 指定的边界处将字符串 string Object 分割成子串创建的。返回的数组中的字串不包括 separator 自身。

例如

var str="How are you doing today?";
var n=str.split(" "); //How,are,you,doing,today?
var str="张三;李四,王五|赵六";
var n=str.split(/[;\|,]/,4); // ["张三", "李四", "王五", "赵六"]

 

RegExp正则

RegExp 对象属性

属性描述
constructor返回一个函数,该函数是一个创建 RegExp 对象的原型。
global判断是否设置了 "g" 修饰符
ignoreCase判断是否设置了 "i" 修饰符
lastIndex用于规定下次匹配的起始位置
multiline判断是否设置了 "m" 修饰符
source返回正则表达式的匹配模式

RegExp 对象方法

方法描述
exec检索字符串中指定的值。返回找到的值,并确定其位置。
test检索字符串中指定的值。返回 true 或 false。
toString返回正则表达式的字符串。

 

常用正则表达式

// 整数最多2位,小数最多3位
/^\d{1,2}(\.\d{1,3})?$/

// 包含两位小数的百分比
/^(((\d|[1-9]\d)(\.\d{1,2})?)|100|100.0|100.00)$/

// 最多输入8位,如果还输入小数则最多保留后两位,并且大于0
/(^[0-9]{1,8}$)|(^[0-9]{1,10}[\.][0-9]{1,2}$)/

// 最多输入10位,如果还输入小数则最多保留后两位,并且大于0,允许输入正负号
/(^(\-|\+)?[0-9]{1,12}$)|(^[0-9]{1,10}[\.]{1}[0-9]{1,2}$)/

// 固定电话
/^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/

利用正则表达式实现输入限制


<a-input @change="e =>validateFields_code(e, 5)" />
// 限制仅允许输入数字及小数点后两位,不限制位数
validateFields_money (e) {
    var value = e.target.value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')
    e.target.value = value
    return value
  }
// 限制仅允许输入数字及小数点后两位,只限制整数位数
validateFields_money_matchlength (e, len) {
    var value = e.target.value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')
    if (value.indexOf('.') != -1) {
      var strs = value.split('.')
      var numStr = strs[0]
      if (numStr.length > len) {
        numStr = numStr.substring(0, len)
      }
      value = numStr + '.' + strs[1]
    } else if (value.length > len) {
      value = value.substring(0, len)
    }
    e.target.value = value
    return value
  }
// 只允许输入整数
<a-input @change="validateFields_money" />
validateFields_num (e) {
    var value = e.target.value.replace(/^\D*(\d*(?:)?).*$/g, '$1')
    e.target.value = value
    return value
  }
// 只允许输入字母和数字,并限制字数
<a-input @change="e =>validateFields_code(e, 5)" />
validateFields_code (e, length) {
    var value = e.target.value.replace(/[^a-zA-Z0-9]/gi, '')
    if (value.length > length) {
      value = value.substring(0, length)
    }
    e.target.value = value
    return value
  },
// 只允许输入字母数字汉字和指定的特殊字符
<a-input @change="validateFields_money" />
validateFields_input_str (e) {
    var value = e.target.value.replace(/[^a-zA-Z\d\u4e00-\u9fa5,。!?()]/g, '')
    e.target.value = value
    return value
  }

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mephisto180502

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值