资讯专栏INFORMATION COLUMN

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

rubyshen / 1790人阅读

摘要:正则表达式巧用匹配特殊字符作者原文章首先声明,本文所有的代码都是在下面运行,需要修改之后才能运行,但是本文没有涉及到太多的新特性,而且由于对修饰符不支持,最后的实现也基本是用的知识写的代码。

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

作者 @zwhu

原文章 @github

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

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

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

在javascript中,$* 都是预定义的特殊字符,不能直接写在正则表达式中,而需要转义,写成 /$/或者/*/
我们需要根据用户的选择来写正则表达式,封装成一个函数就是:

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

这种写法初看上去很美好,将字符都转义之后遇到一些特殊的字符可以匹配,然而现实是残酷的:当用户输入的是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("?")  --> "ud842udfb7"

function reg(input) {
    return new RegExp(`${toUnicode(input)}`)
}
// 再测试一下
reg("$").test("$") --> true

写完啦,看到最后的同学,如果觉得对你有帮助的话,就点个推荐呗。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85992.html

相关文章

  • Python标准库---19、文本处理服务:re正则达式操作

    摘要:正则表达式使用反斜杠来表示特殊形式,或者把特殊字符转义成普通字符。解决办法是对于正则表达式样式使用的原始字符串表示法在带有前缀的字符串字面值中,反斜杠不必做任何特殊处理。为了避免警告,需要将它们用反斜杠转义。 上一篇文章:Python标准库---18、文本处理服务:string 常见的字符串操作下一篇文章: 这个模块提供了与 Perl 语言类似的正则表达式匹配操作。 模式和被搜索的字...

    jcc 评论0 收藏0
  • re模块和字符串处理

    摘要:插入符号匹配字符串的开头,并且在模式也匹配换行后的首个符号。,和修饰符都是贪婪的它们在字符串进行尽可能多的匹配。如果正则式希望找到,它将会匹配整个字符串,而不仅是。用于表示一个字符集合。标记应该在表达式字符串首位表示。 re模块和字符串处理 对于简单的匹配,通常有str.find(),str.endswith(), str.startswith() >>>text = abcd >>>...

    lmxdawn 评论0 收藏0
  • JavaScript 中的正则达式

    摘要:正则表达式的意义中的正则表达式使用表示,可以使用构造函数来创建对象,不过对象更多的是通过一种特殊的直接量语法来创建。用构造函数也可以定义一个与之等价的正则表达式,代码如下正则表达式的模式规则是由一个字符序列组成的。 正则表达式的模式匹配 正则表达式(regular expression)是一个描述字符模式的对象。javascript的RegExp对象表示正则表达式,String和Reg...

    _Dreams 评论0 收藏0
  • Python 正则达式

    摘要:今天就专门看看正则表达式。下面是一个正则表达式最简单的使用例子。这个例子使用了正则表达式模块的函数,它会返回所有符合模式的列表。查询标志让正则表达式具有不同的行为。,按给定正则表达式分割字符串。,正则表达式中捕获组的数量。 最近研究Python爬虫,很多地方用到了正则表达式,但是没好好研究,每次都得现查文档。今天就专门看看Python正则表达式。本文参考了官方文档 re模块。 模式 首...

    FrancisSoung 评论0 收藏0
  • Python正则达式很难?一篇文章搞定他,不是我吹!

    摘要:正则表达式语法字符与字符类特殊字符以上特殊字符要想使用字面值,必须使用进行转义字符类包含在中的一个或者多个字符被称为字符类,字符类在匹配时如果没有指定量词则只会匹配其中的一个。 1. 正则表达式语法 1.1 字符与字符类 1 特殊字符:.^$?+*{}| 以上特殊字符要想使用字面值,必须使用进行转义 2 字符类 1. 包含在[]中的一个或者多个字符被称为字符类,字符类在匹配时如果没有指...

    dcr309duan 评论0 收藏0

发表评论

0条评论

rubyshen

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<