正则表达式之 Unicode 匹配特殊字符

所属分类: 网络编程 / 正则表达式 阅读数: 1080
收藏 0 赞 0 分享

首先声明,本文所有的代码都是在 ES6 下面运行,ES5需要修改之后才能运行,但是本文没有涉及到太多的ES6新特性,而且由于v8对u修饰符不支持,最后的实现也基本是用ES5的知识写的代码。

最初我只是想记录下正则表达式用unicode的方式来匹配特殊字符,写着写着发现 v8 对 u 修饰符的不支持,又转而去研究怎么转换字符串到utf-16的格式,在研究怎么转换的过程中发现ES5的正则对 unicode 编码单元 > 0x10000 的字符串不支持,再转而去实现了一遍对大于 0x10000 的字符串的转换,特此记录。

之前有遇到过一个实用正则表达式匹配特殊字符的需求,例如一段文本 'ab*cd$你好我也好]\nseg$me*ntfault\nhello,world' ,用户可以选择用 * 或者 $ 来分割字符串。

在javascript中, $ 和 * 都是预定义的特殊字符,不能直接写在正则表达式中,而需要转义,写成 /\$/ 或者 /\*/ 。

我们需要根据用户的选择来写正则表达式,封装成一个函数就是:

复制代码 代码如下:

function reg(input) {
    return new RegExp(`\\${input}`)
}

这种写法初看上去很美好,将字符都转义之后遇到一些特殊的字符可以匹配,然而现实是残酷的:当用户输入的是 n 或者 t 这一类的字符的话,返回的正则表达式为 /\n/ 或者 /\t/ ,匹配的就是所有的制表符,这就违背了用户的初衷。

通常有一种写法就是把所有需要转义的特殊字符都列出来,然后再逐一匹配,这种写法很耗费精力,而且可能因为没有统计到的特殊字符而出现漏匹配的情况。

这个时候unicode就隆重登场了,在 JavaScript 中,我们也可以用unicode来表示一个字符,例如 'a' 可以写成'\u{61}', '你' 也可以写成 '\u{4f60}'。

关于unicode的介绍大家可以看 Unicode与JavaScript详解

ES5 中提供了 charCodeAt() 方法来返回指定索引处字符的 Unicode 数值,但是 Unicode 编码单元 > 0x10000 的除外, ES2015 中又增加了一个新的方法 codePointAt() 可以返回大于 0x10000 字符串的数值。返回的数值是十进制的,此时我们还需要通过 toString(16) 转成16进制。

封装之后的函数如下

复制代码 代码如下:

function toUnicode(s) {
    return `\\u{${s.codePointAt().toString(16)}}`
}
toUnicode('$') -> '\u{24}'

重新封装reg函数为

复制代码 代码如下:

function reg(input) {
    return new RegExp(`${toUnicode(input)}`, 'u')
}

其实写到这里,我希望是对的,但是很不幸,V8 不支持 RegExp 的 u 修饰符。V8支持的话,写到这里就应该结束了,没关系,这里只是提供一种用unicode的方式来转义特殊字符的思想。

虽然v8不支持u修饰符,作为一个有追求的码农,当然不能止步于此,我们也可以使用其他方法继续把这个完善

function toUnicode(s) {
 var a = `\\u${utf(s.charCodeAt(0).toString(16))}`
 if(s.charCodeAt(1))
 a = `${a}\\u${utf(s.charCodeAt(1).toString(16))}` 
 return a  
}
function utf(s) {
 return Array.from('00').concat(Array.from(s)).slice(-4).join('')
}
// 这里用var而没有用let声明,是因为这些代码直接复制到 chrome 的控制台下就可以看到执行结果
// 测试一下
// toUnicode('a')  --> "\u0061"
// toUnitcode('��') --> "\ud842\udfb7"
function reg(input) {
 return new RegExp(`${toUnicode(input)}`)
}
// 再测试一下
reg('$').test('$') --> true

以上内容就是脚本之家小编给大家分享的正则表达式之 Unicode 匹配特殊字符

更多精彩内容其他人还在看

正则表达式验证IPV4地址功能实例分析

这篇文章主要介绍了正则表达式验证IPV4地址功能,结合实例形式分析了IPV4地址验证的原理及具体实现技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

正则表达式教程之前后查找lookaround详解

这篇文章主要介绍了正则表达式教程之前后查找lookaround,结合具体问题分析了向前查找及向后查找功能的实现技巧与注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

正则匹配密码只能是数字和字母组合字符串功能【php与js实现】

这篇文章主要介绍了正则匹配密码只能是数字和字母组合字符串功能,涉及针对字符、数字等正则操作相关技巧,并给出了php与js实现示例,需要的朋友可以参考下
收藏 0 赞 0 分享

正则验证不能含有中文的实现方法【jQuery与java实现】

这篇文章主要介绍了正则验证不能含有中文的实现方法,结合jQuery与java两种实现方法分析了针对中文的正则验证操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

JS 密码强度校验的正则表达式(简单且好用)

最近在做一个通行证的项目,在项目中有这样的需求,注册模块中输入密码需要显示密码强度,今天小编给大家分享JS 密码强度校验的正则表达式,简单好用,需要的朋友参考下
收藏 0 赞 0 分享

iOS 正则表达式判断纯数字及匹配11位手机号码的方法

这篇文章主要介绍了iOS 正则表达式判断纯数字及匹配11位手机号码的方法,判断手机号码是否正确的方法很多,我是用正则表达式来完成匹配的,具体方法,大家参考下本文
收藏 0 赞 0 分享

正则表达式(简单易懂篇)

正则表达式是一种可以用于模式匹配和替换的强大工具。这篇文章主要介绍了正则表达式(简单易懂篇),需要的朋友参考下
收藏 0 赞 0 分享

正则表达式实现匹配连续数字的方法

我这两天刚刚学正则表达式。我觉的正则对连续的字符匹配很简单,但是对连续的一段数字匹配就不是很好。正好最近有朋友问了匹配连续数字的正则,就帮忙写了一下,算是当作温习一下吧。下面这篇文章就主要介绍了正则表达式实现匹配连续数字的方法。
收藏 0 赞 0 分享

正则表达式简介及在C++11中的简单使用教程

正则表达式(regular expression)是计算机科学中的一个概念,又称规则表达式,通常简写为regex、regexp、RE、regexps、regexes、regexen。接下来通过本文给大家介绍正则表达式简介及在C++11中的简单使用教程,一起通过本文学习吧
收藏 0 赞 0 分享

正则表达式实现最小匹配功能的方法

这篇文章主要介绍了正则表达式实现最小匹配功能的方法,结合具体实例形式分析了正则表达式最小匹配功能的原理与实现技巧,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多