Java正则表达式小记

正则表达式小记

预定义术语匹配内容
\t水平制表符(tab)
\b空格(blank)
\v垂直制表符(vertical)
\f换页符(form feed)
\r回车(return)
\n换行符
\cA:\cZ控制符,例如:\cM匹配一个Control-M
\x0000:\xFFFF十六进制Unicode码
\x00:\xFF十六进制ASCII码
.匹配除了换行符、回车符、行分隔符和段分隔符以外的任意字符,等价于[^\n\u\u2028\u2029]
\d匹配任意数字(digital),等价于[0-9]
\D匹配任意非数字,等价于[^0-9]
\w匹配包括下划线的任意单词字符(word),等价于[A-Za-z0-9_]
\W匹配任何非单词字符,等价于[^A-Za-z0-9_]
\s匹配任何空白字符(space),包括空格、水平制表符、垂直制表符、换行符、回车符和换页符。等价于[\t\v\n\r\f]
\S匹配任何非空白字符。等价于[^\t\v\n\r\f]
\b匹配单词边界(boundary)
\B匹配非单词边界

由以上可知要想匹配任意字符的话,只要结合它们的对立面即可,可以使用如下任意一个:[\d\D][\w\W][\s\S][^]

3.6 分组:()

到目前为止,我们看到的操作符(如+*)只能影响前面的术语,如果将操作符运用于一组术语,可以像数学表达式一样在该组上使用小括号(),例如/(ab)+/匹配一个或多个连续出现的子字符串'ab'
当正则表达式由一部分是用括号进行分组时,它具有双重责任,同时也创建了所谓的捕获(capture)

如果只想要括号最原始的功能,但不会引用它,即,既不在 API 里引用,也不在正则里反向引用,此时可以使用非捕获括号(因为捕获分组和分支里的数据需要更多的内存来保存这些信息): (?:p)(?:p1|p2|p3),这样就只取到分组的作用。

3.7 或操作符:|

可以使用竖线|)表示或者的关系。例如/a|b/匹配'a'字符或者'b'字符,/(ab)+|(cd)+/表示匹配出现一次或多次的'ab'cd'

3.8 反向引用

正则表达式中最复杂的术语是,在正则中所定义的捕获(capture)反向引用。这种术语表示法就是在反斜杆后面加一个要引用的捕获数字(捕获所在的索引),该数字从1开始,如\1\2等。
举例来说,/^([dnt])a\1/可以匹配任意一个以'd''n''t'开头,且后面跟着一个'a'字符,并且再后面跟着的是和第一个捕获相关字符的字符串(这个很重要!)。比如'dad'就可以正确匹配,而'dan'就不行(因为最后一个'n'字符不是第一个捕获'd'字符)。

因为反向引用,是引用前面的分组,但我们在正则里引用了不存在的分组时,此时正则不会报错,只是匹配反向引用的字符本身。例如\2,就匹配 '\2'注意 '\2'表示对 '2'进行了转义

分组后面有量词的话,分组最终捕获到的数据是最后一次的匹配。例子:

let regex = /(\d)+/
let string = '12345'
console.log( string.match(regex) ) // ["12345", "5", index: 0, input: "12345", groups: undefined]

 
 
  • 1
  • 2
  • 3

从上面看出,分组 (\d)捕获的数据是'5'

反向引用在匹配HTML类型标记的时候会很有用,比如这个正则:
/<(\w+)>(.+)<\/\1>/
要匹配像<strong>whatever</strong>这样的简单元素,不使用反向引用,是无法做到的。因为我们无法知道关闭标签和开始标签是否匹配。

3.9 位置匹配:(?=p)、(?!p)

(?=p),其中p是一个子模式,即p前面的位置,或者说,该位置后面的字符要匹配p。例子:

let result = 'hello'.replace(/(?=l)/g, '#')
console.log(result) // 'he#l#lo'

 
 
  • 1
  • 2

即表示匹配'l'字符前面的位置,然后将该位子替换为'#'result的结果为:'he#l#lo'
(?!p)就是 (?=p)的反面意思。

let result = 'hello'.replace(/(?!l)/g, '#')
console.log(result) // '#h#ell#o#'

 
 
  • 1
  • 2

一般理解(?=p)为:要求接下来的字符与p匹配,但不能包括p匹配的那些字符。
我们也可以理解为p前面的那个位置。对于位置的理解,我们可以理解为空字符'',如'hello'等价于如下的形式:

'hello' == '' + 'h' + '' + 'e' + '' + 'l' + '' + 'l' + '' + 'o' + '';

 
 
  • 1

4. 正则表达式的4种操作

正则表达式主要分4种操作:验证切分提取替换
正则操作的方法共有6个,字符串方法4个,正则方法2个:

这些API不详细解释,不清楚的可以去学习一下。

4.1 验证

比如表单验证,其实就是字符串的匹配操作,如果匹配上了就是验证通过。例子,判断一个字符串中是否有数字,可以采用的验证方法如下:

  • 使用test这个方法最常用
    let regex = /\d/
    let string = 'abc123'
    console.log( regex.test(string) )   // true
    
       
       
    • 1
    • 2
    • 3
  • 使用search
    let regex = /\d/
    let string = 'abc123'
    // 对search的结果先取反,可以排除search结果为0的情况(如string为'0abc'时)
    console.log( !!~string.search(regex) )   // true
    
       
       
    • 1
    • 2
    • 3
    • 4
  • 使用match
    let regex = /\d/
    let string = 'abc123'
    console.log( !!string.match(regex) )   // true
    
       
       
    • 1
    • 2
    • 3
  • 使用exec
    let regex = /\d/
    let string = 'abc123'
    console.log( !!regex.exec(string) )   // true
    
       
       
    • 1
    • 2
    • 3

4.2 切分

使用字符串的split方法可以对字符串进行切分。

  • 例1,目标字符串是'html,css,javascript',按逗号来切分:
    let regex = /,/
    let string = 'html,css,javascript'
    console.log( string.split(regex) )  // ["html", "css", "javascript"]
    

// 当然像这种简单的可以直接用字符串来作为参数
console.log( string.split(’,’) ) // [“html”, “css”, “javascript”]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 例2,目标字符串是'2019/08/13''2019.08.13''2019-08-13',切分出年月日:
    let regex = /\D/
    console.log( '2019/08/13'.split(regex) )   //  ["2019", "08", "13"]
    console.log( '2019.08.13'.split(regex) )   //  ["2019", "08", "13"]
    console.log( '2019-08-13'.split(regex) )   //  ["2019", "08", "13"]
    
      
      
    • 1
    • 2
    • 3
    • 4
  • 4.3 提取

    有时匹配上了,我们想要提取部分匹配的数据,这时通常要使用分组引用(分组捕获)功能,还要配合使用相关的API。这里,还是以日期为例,提取出年月日。注意下面正则中的括号:

    • 使用match这个方式最为常用
      let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/
      let string = '2019-08-13'
      console.log( string.match(regex) )   
      // =>  ["2019-08-13", "2019", "08", "13", index: 0, input: "2019-08-13", groups: undefined]
      
         
         
      • 1
      • 2
      • 3
      • 4
    • 使用exec
      let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/
      let string = '2019-08-13'
      console.log( regex.exec(string) )   
      // =>  ["2019-08-13", "2019", "08", "13", index: 0, input: "2019-08-13", groups: undefined]
      
         
         
      • 1
      • 2
      • 3
      • 4
    • 使用test
      let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/
      let string = '2019-08-13'
      regex.test(string)
      // 执行完test方法后,RegExp全局属性$1、$2、$3...的值为对应分组的匹配值
      console.log( RegExp.$1, RegExp.$2, RegExp.$3 ) // "2019" "08" "13"
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
    • 使用search
      let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/
      let string = '2019-08-13'
      string.search(regex)
      // 执行完search方法后,RegExp全局属性$1、$2、$3...的值为对应分组的匹配值
      console.log( RegExp.$1, RegExp.$2, RegExp.$3 ) // "2019" "08" "13"
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
    • 使用replace
      let regex = /^(\d{4})\D(\d{2})\D(\d{2})$/
      let string = '2019-08-13'
      let date = []
      string.replace(regex, (match, year, month, day) => {
      	date.push(year, month, day)
      });
      console.log(date); // ["2019", "08", "13"]
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    4.4 替换

    找,往往不是目的,通常下一步是为了替换。在 JavaScript 中,使用 replace进行替换。
    比如把日期格式,从 yyyy-mm-dd替换成 yyyy/mm/dd

    let string = '2019-08-13'
    console.log( string.replace(/-/g, '/') )  // "2019/08/13"
    
     
     
    • 1
    • 2

    replace方法很强大,需要重点掌握。

    4.5 强大的replace

    总体来说 replace 有两种使用形式,这是因为它的第二个参数,可以是字符串,也可以是函数。

    • 当第二个参数是字符串时,如下的字符有特殊的含义:

    属性描述
    $1$2、····,$99匹配第 1-99 个 分组里捕获的文本
    $&匹配到的子串文本
    $`匹配到的子串的左边文本
    $'匹配到的子串的右边文本
    $$美元符号

    例如,把 '2,3,5',变成 '5=2+3'

    let result = '2,3,5'.replace(/(\d+),(\d+),(\d+)/, '$3=$1+$2')
    console.log(result)   // 5=2+3
    
     
     
    • 1
    • 2

    又例如,把 '2,3,5',变成 '222,333,555'

    let result = '2,3,5'.replace(/(\d+)/g, '$&$&$&')
    console.log(result)   // 222,333,555
    
     
     
    • 1
    • 2

    再例如,把 '2+3=5',变成 '2+3=2+3=5=5'

    let result = '2+3=5'.replace(/=/, "$&$`$&$'$&")
    // $&匹配到的是'=',$`这个匹配到的是'2+3',$'匹配到的是'5'
    console.log(result)   // 2+3=2+3=5=5
    
     
     
    • 1
    • 2
    • 3
  • 当第二个参数是函数时,我们需要注意该回调函数的参数具体是什么:

    '1234 2345 3456'.replace(/(\d)\d{2}(\d)/g, (match, $1, $2, index, input) => {
    	console.log([match, $1, $2, index, input])
    })
    // ["1234", "1", "4", 0, "1234 2345 3456"]
    // ["2345", "2", "5", 5, "1234 2345 3456"]
    // ["3456", "3", "6", 10, "1234 2345 3456"]
    
      
      
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 4.6 注意点

    在使用正则的过程中,以下的一些点需注意

    • 字符串 4 个方法参数都支持正则和字符串,但 searchmatch方法会把字符串转换为正则的。
      let string = '2019.08.13'
      console.log( string.search('.') )  //  0
      //需要修改成下列形式之一
      console.log( string.search('\\.') )  // 4
      console.log( string.search(/\./) )  // 4
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
    • match返回结果的格式,与正则对象是否有修饰符g有关。
      let string = '2019.08.13'
      let regex1 = /\b(\d+)\b/
      let regex2 = /\b(\d+)\b/g
      console.log( string.match(regex1) ) // ["2019", "2019", index: 0, input: "2019.08.13", groups: undefined]
      console.log( string.match(regex2) )  // ["2019", "08", "13"]
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
      没有g,返回的是标准匹配格式,即,数组的第一个元素是整体匹配的内容,接下来是分组捕获的内容,然后是整体匹配的第一个下标,最后是输入的目标字符串。有 g,返回的是所有匹配的内容。当没有匹配时,不管有无g,都返回null
    • execmatch更强大
      当正则没有g时,使用 match返回的信息比较多。但是有 g后,就没有关键的信息 index了。而 exec方法就能解决这个问题,它能接着上一次匹配后继续匹配:
      let string = '2019.08.13'
      let regex2 = /\b(\d+)\b/g
      console.log( regex2.exec(string) ) // ["2019", "2019", index: 0, input: "2019.08.13", groups: undefined]
      // lastIndex 属性,表示下一次匹配开始的位置
      console.log( regex2.lastIndex)  // 4
      console.log( regex2.exec(string) )  // ["08", "08", index: 5, input: "2019.08.13", groups: undefined]
      console.log( regex2.lastIndex)  // 7
      console.log( regex2.exec(string) )  // ["13", "13", index: 8, input: "2019.08.13", groups: undefined]
      console.log( regex2.lastIndex)  // 10
      console.log( regex2.exec(string) )  // null
      console.log( regex2.lastIndex)  // 0
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      从上述代码看出,在使用 exec时,经常需要配合使用while循环:
      let string = '2019.08.13'
      let regex2 = /\b(\d+)\b/g
      let result
      while ( result = regex2.exec(string) ) {
      	console.log( result, regex2.lastIndex );
      }
      // ["2019", "2019", index: 0, input: "2019.08.13", groups: undefined] 4
      // ["08", "08", index: 5, input: "2019.08.13", groups: undefined] 7
      // ["13", "13", index: 8, input: "2019.08.13", groups: undefined] 10
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 修饰符g,对exextest的影响
      上面提到了正则实例的 lastIndex属性,表示尝试匹配时,从字符串的 lastIndex位开始去匹配。字符串的四个方法,每次匹配时,都是从 0 开始的,即 lastIndex属性始终不变。
      而正则实例的两个方法 exectest,当正则是全局匹配时,每一次匹配完成后,都会修改lastIndex。下面
      让我们以 test为例,看看你是否会迷糊:
      let regex = /a/g
      // 每次调用都会从 lastIndex 下标处开始查找
      console.log( regex.test('a'), regex.lastIndex )  // true 1
      console.log( regex.test('aba'), regex.lastIndex )  // true 3
      console.log( regex.test('ababc'), regex.lastIndex )  // false 0
      
         
         
      • 1
      • 2
      • 3
      • 4
      • 5
      如果没有 g,自然都是从字符串第 0 个字符处开始尝试匹配:
      let regex = /a/
      console.log( regex.test('a'), regex.lastIndex )  // true 0
      console.log( regex.test('aba'), regex.lastIndex )  // true 0
      console.log( regex.test('ababc'), regex.lastIndex )  // true 0
      
         
         
      • 1
      • 2
      • 3
      • 4
    • test整体匹配时需要同时使用 ^$
      test方法只是查看目标字符串中是否有字串匹配正则,只要有部分匹配则返回true。如果需要整体匹配,正则前后需要添加开头和结尾。
      console.log( /123/.test('a123b') )   // true
      console.log( /^123$/.test('a123b') )  // false
      console.log( /^123$/.test('123') )  // true
      
         
         
      • 1
      • 2
      • 3
    • split需要注意的两点
      第一,它可以有第二个参数,表示结果数组的最大长度:
      let string = 'html,css,javascript'
      console.log( string.split(/,/, 2) )  // ["html", "css"]
      
         
         
      • 1
      • 2
      第二,正则使用分组时,结果数组中是包含分隔符的:
      let string = 'html,css,javascript'
      console.log( string.split(/(,)/) )  // ["html", ",", "css", ",", "javascript"]
      
         
         
      • 1
      • 2

    5. 练习

    5.1 匹配16进制颜色值

    像:#AAfa10#ABC#111
    思路

    • 16进制每一位的所有可能取值为0~9,A ~ F或a ~ f:[0-9A-Fa-f]
    • 位数可以为3位或者6位:/#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})/

    5.2 匹配数字时钟

    像:23:5901:0019:50
    思路(一共四位数字,它们之间有约束):

    • 第一位数字为0、1或2
    • 当第一位为0和1时,第二位可为0~9中的一个:[01][0-9],因为[0-9]可用\d表示,那么也可为[01]\d
    • 当第一位为2时,第二位可为0~3中的一个:2[0-3]
    • 那么第一位和第二位的组合为:[01]\d|2[0-3]
    • 第三位可为0~5中的一个:[0-5]
    • 第四位为0~9中的一个:\d
    • 最后组合一起:/([01]\d|2[0-3]):[0-5]\d/

    若也要支持时和分前面的0忽略的情况,那么可为:/(0?\d|1\d|2[0-3]):(0?\d|[1-5]\d)/

    5.3 日期的匹配

    比如:yyyy-mm-dd的格式。
    思路

    • 年份的四位为数字即可\d{4}
    • 月份分首位为0和1的情况
    • 当月份首位为0,那么第二位可为1~9中的一个:0[1-9]
    • 当月份首位为1,那么第二位可为0~2中的一个:1[0-2]
    • 那月份可为0[1-9]|1[0-2]
    • 日首位有0、1、2、3四种
    • 当日首位为0时,第二位可为1~9中的一个:0[1-9]
    • 当日首位为1或2时,第二位可为0~9中的一个:[12]\d
    • 当日首位为3时,第二位只能为0和1:[01]
    • 所以日的组合为:0[1-9]|[12]\d|3[01]
    • 最终组合为:/\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])/

    这里其实有问题,2月份是个特殊的例子,大家自己想想应该如何解决。

    5.4 windows操作系统的文件路径匹配

    比如:D:\study\javascript\RegExp\regular expression.pdfD:\study\javascript\RegExp\D:\study\javascriptD:\
    思路

    • 匹配D:\,盘符不区分大小写,\需要转义:[a-zA-Z]:\\
    • 文件夹或文件名不能包含特殊字符:[^\\:*<>|“?\r\n/]
    • 并且它们不能为空,因此匹配文件夹\为:[^\\:*<>|“?\r\n/]+\\
    • 文件夹\可以出现任意次:([^\\:*<>|“?\r\n/]+\\)*
    • 路径的最后一部分可以是文件夹,没有\,所以要添加:([^\\:*<>|“?\r\n/]+)?
    • 最终:/[a-zA-Z]:\\([^\\:*<>|“?\r\n/]+\\)*([^\\:*<>|“?\r\n/]+)?/

    5.5 将数字改成千分位符表示法

    比如将12345678变为12,345,678
    思路

    • 需要使用位置匹配(?=p),从最末尾开始计算,每三位数字前加一个',',先弄出最后一个逗号,此时(?=p)中的p即为\d{3}$/(?=\d{3}$)/g,此时'12345678'.replace(/(?=\d{3}$)/g, ',')变为12345,678
    • 因为逗号出现的位置,要求后面3个数字为一组,也就是\d{3}至少出现一次,此时可以使用量词'+',弄出所有逗号:/(?=(\d{3})+$)/g, 此时'12345678'.replace(/(?=(\d{3})+$)/g, ',')变为12,345,678
    • 不知道你发现没,这里会出现一个问题,匹配的数字串位数如果刚好是3的倍数的话,那么第一个字符就会变为',',如'123456'.replace(/(?=(\d{3})+$)/g, ',')变为,123,456,这不是我们想要的。所以我们要排除掉开头的位置,可以使用(?!^),那么最终的匹配模式为:/(?!^)(?=(\d{3})+$)/g'123456'.replace(/(?!^)(?=(\d{3})+$)/g, ',')变为123,456

    应用例子,货币的格式化,比如将1888转化为$ 1,888.00,代码如下:

    function format (num) {
    	// $$ 即表示 $ 符号
        return num.toFixed(2).replace(/\B(?=(\d{3})+\b)/g, ',').replace(/^/, '$$ ');
    };
    console.log(format(1888))  // '$ 1,888.00'
    console.log(format(1564312.62165))  // '$ 1,564,312.62'
    
     
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.6 密码验证

    假设密码长度要求为6~12位,由数字、大写字母和小写字母组成,并且必须至少包括两种字符。
    思路

    • 首先,不考虑至少包括两种字符的话,那很好写出来:/^[0-9A-Za-z]{6,12}$/
    • 其次,更进一步,假如必须包含数字的话,那么我们可以通过(?=.*[0-9])来实现。则正则变为:/(?=.*[0-9])^[0-9A-Za-z]{6,12}$/,这个正则(?=.*[0-9])^这部分理解了就搞懂整个了。(?=.*[0-9])^分开来看就是(?=.*[0-9])^,表示开头前面还有一个位置(当然也是开头,即同一个位置,想想之前的空字符类比)。(?=.*[0-9])表示该位置后面的字符匹配 .*[0-9],即,有任何多个任意字符,后面再跟个数字。翻译成大白话,就是接下来的字符,必须包含个数字。
    • 需同时包含数字和小写字母的话,可用(?=.*[0-9])(?=.*[a-z])来实现,则正则变为:/(?=.*[0-9])(?=.*[a-z])^[0-9A-Za-z]{6,12}$/
    • 有了以上,我们只要组合一下即可得出最后的答案:/((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[ 0-9A-Za-z]{6,12}$/

    另一种思路,至少包含两种字符的意思即为:不能全为数字、不能全为小写字母,不能全为大写字母。简单开始,那么不能全为数字该怎么实现?需要这个(?!p)来匹配了:/(?!^[0-9]{6,12}$)^[0-9A-Za-z]{6,12}$/,那么三个都不能的话,最终结果为:/(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/

    5.7 模拟字符串的trim方法

    trim方法用来去掉字符串首尾的空白符。
    思路:找到字符串开头和结尾的所有空白符,将其替换为空字符''即可。

    function trim(str) {
        return str.replace(/^\s+|\s+$/g, '')
    }
    console.log( trim('     javascript        ') ) // 'javascript'
    
     
     
    • 1
    • 2
    • 3
    • 4

    5.8 将每个单词的首字母转为大写

    比如将'my name is javascript'转化为'My Name Is Javascript'
    思路:关键点在于如何找到字符串的每个单词的首字母,使用/(?:^|\s)\w/g即可,即开头或者空白字符后面的第一个任意单词字符。
    则可以通过如下代码实现:

    function titleize (str) {
    	//这里不使用非捕获匹配也是可以的:/(^|\s)\w/g
        return str.toLowerCase().replace(/(?:^|\s)\w/g, c => c.toUpperCase())
    }
    console.log( titleize('my name is javascript') ) // 'My Name Is Javascript'
    
     
     
    • 1
    • 2
    • 3
    • 4
    • 5

    5.9 驼峰化

    比如将'-moz-transform'转化为'MozTransform'
    思路:其实主要还是怎么找到单词的首字母,将首字母变为大写,单词之间的内容去除。

    function camelize (str) {
        return str.replace(/[-_\s]+(.)?/g, (match, c) => c ? c.toUpperCase() : '')
    }
    console.log( camelize('-moz-transform') ) // 'MozTransform'
    
     
     
    • 1
    • 2
    • 3
    • 4

    上面的代码中,(.)即为首字母,单词的界定是,前面的字符可以是多个连字符'-'、下划线'_'以及空白符。正则后面
    '?'的目的,是为了应对 str 尾部的字符可能不是单词字符,比如 str 是 '-moz-transform '

    反之,将驼峰写法中划线化

    function dasherize (str) {
    	return str.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
    }
    console.log( dasherize('MozTransform') ); // '-moz-transform'
    
     
     
    • 1
    • 2
    • 3
    • 4

    5.10 HTML转义与反转义

    // 将HTML特殊字符转换成等值的实体
    function escapeHTML (str) {
    	const escapeChars = {
    	'<' : 'lt',
    	'>' : 'gt',
    	'"' : 'quot',
    	'&' : 'amp',
    	'\'' : '#39'
    	}
    	//'[' + Object.keys(escapeChars).join('') +']', 结果即为:[<>"&']
    	return str.replace(new RegExp('[' + Object.keys(escapeChars).join('') +']', 'g'), match => '&' + escapeChars[match] + ';')
    }
    console.log( escapeHTML('<div>Blah blah blah</div>') ); // '&lt;div&gt;Blah blah blah&lt;/div&gt;'
    
     
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    逆过程:

    // 实体字符转换为等值的HTML。
    function unescapeHTML (str) {
    	const htmlEntities = {
    		nbsp: ' ',
    		lt: '<',
    		gt: '>',
    		quot: '"',
    		amp: '&',
    		apos: '\''
    	};
    	return str.replace(/\&([^;]+);/g, (match, key) => key in htmlEntities ? htmlEntities[key] : match )
    }
    console.log( unescapeHTML('&lt;div&gt;Blah blah blah&lt;/div&gt;') ); // '<div>Blah blah blah</div>'
    
     
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    通过 key 获取相应的分组引用,然后作为对象的键。

    写在最后:正则虽然很强大,但也没必要事事都用正则,有时字符串自带的API使用起来会更为简单且易于理解。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript正则表达式Java正则表达式在语法上有一些差异,但是它们的基本概念和用法是相似的。下面是将JavaScript正则表达式转换为Java正则表达式的一些常见规则: 1. 语法差异: - JavaScript正则表达式使用斜杠(/)作为定界符,而Java正则表达式使用双引号(")作为定界符。 - JavaScript正则表达式中的特殊字符需要进行转义,而Java正则表达式中的特殊字符不需要转义。 2. 字符类: - JavaScript正则表达式中的字符类使用方括号([])表示,而Java正则表达式中使用方括号([])或者Unicode转义(\p{...})表示。 - JavaScript正则表达式中的字符类可以使用连字符(-)表示范围,而Java正则表达式中需要使用Unicode转义(\uXXXX)表示范围。 3. 量词: - JavaScript正则表达式中的量词使用花括号({})表示,而Java正则表达式中使用花括号({})或者问号(?)表示。 - JavaScript正则表达式中的贪婪量词默认是贪婪模式,而Java正则表达式中的贪婪量词需要在后面添加问号(?)来表示非贪婪模式。 4. 边界匹配: - JavaScript正则表达式中的边界匹配使用插入符号(^)和美元符号($)表示,而Java正则表达式中使用\A和\Z表示。 5. 其他差异: - JavaScript正则表达式中的捕获组使用圆括号(())表示,而Java正则表达式中使用圆括号(())或者方括号([])表示。 - JavaScript正则表达式中的反向引用使用反斜杠加数字(\1、\2等)表示,而Java正则表达式中使用美元符号加数字($1、$2等)表示。 以上是一些常见的JavaScript正则表达式转换为Java正则表达式的规则。具体转换时,还需要根据具体的正则表达式进行适当的调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值