马黑黑 发表于 2023-1-20 10:52

正则表达式之单词边界

<style>
#mydiv {
        border: 1px solid #ccc;
        padding: 10px;
}

</style>
<h2>正则表达式:单词边界与非单词边界</h2>
<p><br></p>
<div id="mydiv" contenteditable></div>
<p><br><input id="bb" type="button" value="匹配: \b"/> <input id="BB" type="button" value="匹配: \B"/> <input id="reset" type="button" value="重置"/></p>

<script>
let mystr = 'Do it.';
mydiv.innerText = mystr;

bb.onclick = () => {
        let str = 'Do it.';
        let re = /\b/g;
        mydiv.innerHTML = mydiv.innerText.replace(re,'<span style="color:red">,</span>');
}

BB.onclick = () => {
        let re = /\B/g;
        mydiv.innerHTML = mydiv.innerText.replace(re,'<span style="color:red">,</span>');
}

reset.onclick = () => {
        mydiv.innerText = mystr;
}


</script>

马黑黑 发表于 2023-1-20 11:05

正则表达式单词边界

之前我们在一些帖子中提及过字符串的开始边界 ^ 和字符串的结束边界 $,它们用于界定字符串的匹配“长度”,等效于一整行或一整个字符串的范围。我们先来复习一下,让我们看看如下JS代码:

        let mytext = '一二三四五六';
        let re = /^|$/g;
        let outstr = mytext.replace(re,'?');
        console.log(outstr);

代码中,我们定义了一个字符串 mytext,还有一个匹配规则 ^|$ 表示开始或结束处,我们加入了全局变量 g 以便让正则在匹配时去匹配所有的匹配内容。接着我们声明一个变量 outstr 用来存储 mytext 正则替换结果,我们将开始和结束位置替换为小角问号 ? ,最后将 outstr 在控制台显示出来。结果将是:

        ?一二三四五六?

从字符起始处的操作中,我们可以理解:字符串的头尾边界不包含字符串自身的任何内容,它们是基于位置而非字符串,该位置用于框定一个字符串的开始处或结束处;位置可以替换为字符,正如上例中我们给字符串的头尾都加上了问好,此时的字符串第一个问号的前面位置是起始位置 ^,第二个问号的后面位置是结束位置 $。

字符串内部也有分界符号,这就是本帖要重点介绍的单词分界。

正则表达式中的所谓“单词”,指由字母、数字和(或)下划线构成的彼此不分开的单位,一个单词可以是纯字母组成,也可以是纯数字组成,也可以是纯下划线,也可以是由字母、数字、下划线任意两种或三种共同组成。下面的例子,都是正则表达式中的单词:

        a,A,1,_,abc,123,__,aA_1,12_abc,__xyz,22_xy,_89

那么,单词的分界是不是指单词的两边?也是,也不是,就是说的这个描述不够准确。准确地讲,单词的边界是指单词开始和结尾处与两边的不是单词的可见或不可见的字符之间的位置。举例说明一下,看下面的示例:

        Do it.

上面句子共有两个单词。每个单词前后各有一个分界符,Do 前有一个,它是D与前面开始符 ^ 之间的位置,用逗号表示该位置,先记为:,Do;Do后面,o与其后的空格间的位置,也用逗号表示,于是,Do整体记为 ,Do,;it 同样有两个单词分界符,i与其前面的空格间的位置、t与其后句号 . 的位置。至此,整个句子记为:

        ,Do, ,it,.

现在,我们应该理解了单词边界的含义。接下来,了解正则表达式的单词分界符号:

        \b

b是boundary的缩写,边界之意(助记:b→边)。正则表达式用 \b 表示单词边界,我们现在就用它来查找单词边界并用逗号将边界位置标志出来:

        let str = 'Do it.';
        let re = /\b/g;
        console.log(str.replace(re,','));

这将得出我们前面分析单词边界举例的最后结果:,Do, ,it,.。

我们应该注意的是:单词边界仅指单词与非单词符号(含可见和不可见的符号)之间的位置,该位置在自然文本流中不占用空间(除非像在HTML中那样设置了字间距)。我们还应该注意的是:正则表达式中的所谓“单词”,指由字母、数字、下划线或单独、或两种和多种组成的不分开的单位,w 是一个单词,ww 也是一个单词;2 是一个单词,22 也是一个单词;_ 是一个单词,__也是一个单词;w2 是单词,w2_ 也是单词,2_ 也是单词……

正则中的单词分界还有一个与 \b 对立的符号,\B ,它是 \b 的取反,意思指不是单词分界的位置。让我们仍以 Do it. 为例,把正则表达式的 \b 改为 \B,这时,代表 \B 位置的小角逗号插入的地方,就是 \B 的位置:

        D,o i,t.,

D开头之前没有不是单词边界位置,D和o之间有一个,i和t之间有一个,这些都好理解。可是,. 后面为什么也有一个呢?因为,. 和 $ 之间不是单词,所以存在一个非单词分界;这与D前面不一样,D 是单词的组成成员,它 和 ^ 之间是单词和 ^ 的位置,不是非单词边界位置。

单词边界和非单词边界在正则表达式的应用中非常重要,诸如检索单词、中文等,灵活配套使用 \b 和 \B 去匹配可以大大减少工作量、提升检索效率。

红影 发表于 2023-1-20 16:51

大小写的情况下,意义完全相反呢{:4_173:}

红影 发表于 2023-1-20 16:53

这个单词分界是用空格和其他非特定规定的字符来判断的么?很厉害,可以直接把单词找出来{:4_187:}

红影 发表于 2023-1-20 16:55

空格也不是单词, \B 为什么不管空格呢?

马黑黑 发表于 2023-1-20 19:21

红影 发表于 2023-1-20 16:55
空格也不是单词, \B 为什么不管空格呢?

它只管单词。不论是空格还是别的,\b 都不管。没有“单词”(就是 \w 代表的字母数字下划线)\b 就不会匹配。

马黑黑 发表于 2023-1-20 19:26

红影 发表于 2023-1-20 16:51
大小写的情况下,意义完全相反呢

这只是规定

红影 发表于 2023-1-20 20:26

马黑黑 发表于 2023-1-20 19:21
它只管单词。不论是空格还是别的,\b 都不管。没有“单词”(就是 \w 代表的字母数字下划线)\b 就不会匹 ...

还是\b 比较容易懂。

红影 发表于 2023-1-20 20:28

马黑黑 发表于 2023-1-20 19:26
这只是规定

嗯嗯,只要记住这个规定就好。

马黑黑 发表于 2023-1-20 20:50

红影 发表于 2023-1-20 20:26
还是\b 比较容易懂。

相反的同样容易理解

红影 发表于 2023-1-21 11:09

马黑黑 发表于 2023-1-20 20:50
相反的同样容易理解

这个能派什么用途呢?

马黑黑 发表于 2023-1-21 11:39

红影 发表于 2023-1-21 11:09
这个能派什么用途呢?

用处多多,只是你想象不到。

红影 发表于 2023-1-21 12:37

马黑黑 发表于 2023-1-21 11:39
用处多多,只是你想象不到。

那是当然,我对代码本来就不熟啊{:4_173:}

马黑黑 发表于 2023-1-21 13:24

红影 发表于 2023-1-21 12:37
那是当然,我对代码本来就不熟啊

没关系

红影 发表于 2023-1-21 23:13

马黑黑 发表于 2023-1-21 13:24
没关系

就算有关系也没办法啊{:4_173:}

马黑黑 发表于 2023-1-21 23:30

红影 发表于 2023-1-21 23:13
就算有关系也没办法啊

没办法找办法也要有撇清关系

红影 发表于 2023-1-22 13:31

马黑黑 发表于 2023-1-21 23:30
没办法找办法也要有撇清关系

不撇清,努力跟代码搭上关系才是正事{:4_173:}

马黑黑 发表于 2023-1-22 14:03

红影 发表于 2023-1-22 13:31
不撇清,努力跟代码搭上关系才是正事

有决心

红影 发表于 2023-1-22 18:10

马黑黑 发表于 2023-1-22 14:03
有决心

必须的{:4_178:}

马黑黑 发表于 2023-1-22 18:29

红影 发表于 2023-1-22 18:10
必须的

{:4_190:}
页: [1]
查看完整版本: 正则表达式之单词边界