Commit 7b98c7c8 authored by anrun's avatar anrun
parents 423ad55c 398d1af1
Pipeline #17185 canceled with stage
---
title: JavaScript中的正则表达式(二)
date: 2022/11/13 16:10:00
tags:
- JS
- 正则表达式
- author: 张顺
---
##
上一节对正则介绍以及创建基础使用有个简单的介绍,下面将对正则表达式的几种常用模式分别介绍下使用 方括号查询使用、元字符查询使用、量词查询使用
#### 正则表达式模式
方括号查询范围内符合的内容,在方括号中可以包含多个字符,表示匹配其中任意一个字符。如果多个字符的编码顺序是连续的,可以仅指定开头和结尾字符,省略中间字符,仅使用连字符~表示。如果在方括号内添加脱字符^前缀,还可以表示范围之外的字符。例如: (注意:中括号内不能有空格 ,否则会误解为还要匹配空格)
| 正则表达式模式 | 说明 |
| ---- | ---- |
| `(x|y)` | 查找任何以 `|`分隔的选项。 |
| [abc] | 查找方括号内任意一个字符。 |
| [^abc]| 查找不在方括号内的字符。|
| [0-9] | 查找从 0 至 9 范围内的数字,即查找数字。|
| [a-z] | 查找从小写 a 到小写 z 范围内的字符,即查找小写字母。|
| [A-Z] | 查找从大写 A 到大写 Z 范围内的字符,即查找大写字母。|
| [A-z] | 查找从大写 A 到小写 z 范围内的字符,即所有大小写的字母。|
如果匹配任意大小写字母和数字,存在即为真
```js
let str= 'hello steven'
let r = /[a-zA-Z0-9]/g;
console.log(r.test(str))
```
在字符范围内可以混用各种字符模式。
```js
var s = "abcdez"; //字符串直接量
var r = /[abce-z]/g; //字符a、b、c,以及从e~z之间的任意字符
var a = s.match(r);
var b = r.test(s);
console.log(a) //返回数组["a","b","c","e","z"]
console.log(b) //返回true
```
字符范围可以组合使用。
```js
var s = "abc4abd6abe3abf1abg7"; //字符串直接量
var r = /ab[c-g][1-7]/g; //前两个字符为ab,第三个字符为从c到g,第四个字符为1~7的任意数字
var a = s.match(r);
console.log(a) //返回数组["abc4","abd6","abe3","abf1","abg7"]
```
反义字符范围可以匹配很多无法直接描述的字符
```js
var str='873195'
var r = /[^01234]/g;
console.log(str.match(r))  //返回数组 ['8', '7', '9', '5']
```
匹配任意数字或字母,使用竖线|描述,表示在两个子模式的匹配结果中任选一个
```js
var str = '你好程序猿,hellow word 123'
var r = /\w+|\d+/;
console.log(r.test(str)) // 返回true
```
可以定义多重选择模式
```js
var str = 'abcdefghellow123word45612345753'
var r = /(abc)|(efg)|(123)|(456)/;
console.log(str.match(r))
```
元字符是拥有特殊含义的字符
| 元字符 | 说明 | 例子 |
| ---- | ---- | ---- |
| \d | 查找数字。| `var str="Give 100%!"; var patt1=/\d/g; console.log(str.match(patt1))  结果 ['100']` |
| \D | 查找非数字字符 | `var str="Give 100%!"; var patt1=/\D+/g; console.log(str.match(patt1))  结果 ['Give ', '%!'] `|
| \s | 查找空白字符。| `var str="Is this all there is?"; var patt1=/\s/g;  结果 [' ', ' ', ' ', ' ']` |
| \S | 查找非空白字符 |`var str="Is this all there is?";var patt1=/\S+/g;;  结果 ['Is', 'this', 'all', 'there', 'is?']` |
| \b | 匹配单词边界 | `var str="Visit Runooob"; var patt1=/\bRun/g; console.log(str.match(patt1)) 结果 ['Run']`|
| \B | 匹配非单词边界 | `var str="Visit Runooob" var patt1=/\Bnooob/g; console.log(str.match(patt1)) 结果 ['nooob'] `|
| \w | 查找单词字符 (包含a-z、A-Z、0-9,以及下划线, 包含 _ (下划线) 字符)| `var str="Give 100%!"; var patt1=/\w/g 结果 ['Give', '100'];`|
| \W | 查找非单词字符 | `var str="Give 100%!"; var patt1=/\W+/g; console.log(str.match(patt1))  结果 [' ', '%!'] `|
| \n | 查找换行符 | `var str="Visit RUNOOB.\nLearn Javascript.";var patt1=/\n/; console.log(str.match(patt1)) 结果 ['\n', index: 13, input: 'Visit RUNOOB.\nLearn Javascript.', groups: undefined]`|
| \f | 查找换页符 |
| \r | 查找回车符 |
```js
var s = "how are you"
var r = /\w+$/;
var a = s.match(r); //返回数组["you"]
```
```js
var r = /^\w+/;
var a = s.match(r); //返回数组["how"]
```
```js
var r = /\w+/g;
var a = s.match(r); //返回数组["how","are","you"]
```
量词:
| 元字符 | 说明 | 例子 |
| ---- | ---- | ----- |
| ^ | 匹配开头,在多行检测中,会匹配一行的开头| `对字符串开头的 "Is" 进行全局搜索: var str="Is this his"; var patt1=/Is$/g;` |
| $ | 匹配结尾,在多行检测中,会匹配一行的结尾| `对字符串结尾的 "is" 进行全局搜索: var str="Is this his"; var patt1=/is$/g;` |
| n+ | 匹配任何包含至少一个 n 的字符串。| `例如,/a+/ 匹配 "candy" 中的 "a","caaaaaaandy" 中所有的 "a"。`|
| n* | 匹配任何包含零个或多个 n 的字符串。| `例如,/bo*/ 匹配 "A ghost booooed" 中的 "boooo","A bird warbled" 中的 "b",但是不匹配 "A goat grunted"。`|
| n? | 匹配任何包含零个或一个 n 的字符串。 | `例如,/e?le?/ 匹配 "angel" 中的 "el","angle" 中的 "le"。`|
| n{x} | 匹配包含 x 个 n 的序列的字符串| `例如,/a{2}/ 不匹配 "candy," 中的 "a",但是匹配 "caandy," 中的两个 "a",且匹配 "caaandy." 中的前两个 "a"。`|
| n{x,y} | 匹配包含最少 x 个、最多 y 个 n 的序列的字符串,包括y个 | `例如,/a{1,3}/ 不匹配 "cndy",匹配 "candy," 中的 "a","caandy," 中的两个 "a",匹配 "caaaaaaandy" 中的前面三个 "a"。注意,当匹配 "caaaaaaandy" 时,即使原始字符串拥有更多的 "a",匹配项也是 "aaa"。`|
| n{x,} | 匹配包含至少 x 个 n 的序列的字符串 | `例如,/a{2,}/ 不匹配 "candy" 中的 "a",但是匹配 "caandy" 和 "caaaaaaandy." 中所有的 "a"。`|
---
title: 前端实现elementUI树状表格的模糊搜索、关键字高亮...
date: 2022/11/29 08:42:20
tags:
- 前端
- JavaScript
author: 李燕
---
话说,elementUI的el-table组件在本人的项目中,已经应用很多次了。
但是el-table的树状表格功能,本人这两天才第一次用到。参照文档,按照指定格式赋值data,树状表格很容易就渲染成功了。
但是,接下来的,基于树状表格的延伸功能,就费了一点小心思了,故此记录一下(以下功能实现全部基于Vue2+elementUI项目)。
<!-- more -->
### 一、前端实现树状表格的模糊搜索
**功能要求:**
若父节点有,则该父节点下的所有子节点返回;若父节点没有,但子节点有,则该子节点及以上层级的父节点均需返回。
**实现重点:**
1. 关键字匹配(`name.indexOf(keyWords) > -1`
2. 匹配到的数据重新组装成树形结构(循环、递归)
**方法封装:**
```js
/**
* @param treeData 原始树形数据
* @param inputValue 用户搜索的关键字
* @param key 被匹配的对象(键名)
* @return Array 匹配到的树形数据
*/
filterTree(treeData, inputValue, key) {
let newTreeData = [];
treeData.forEach(item => {
if (item[key].indexOf(inputValue) > -1) {
newTreeData.push(item)
} else {
if (item.children && item.children.length > 0) {
// 父级不匹配,继续向下查询子级是否匹配
const arr = this.filterTree(item.children, inputValue, key);
// 如果子级匹配,将符合条件的子级和父级push到目标数组中
if (arr && arr.length > 0) {
const obj = {
...item,
children: arr
};
newTreeData.push(obj);
}
}
}
});
return newTreeData;
},
```
**延伸:**
若父节点有,仍需继续向下查询子节点是否匹配,而不是子节点全部返回,怎么处理?
将上述if里面的代码改成如下即可。
```js
if (item[key].indexOf(inputValue) > -1) {
// 父级匹配,继续向下查询子级是否匹配
const arr = this.filterTree(item.children, inputValue, key);
const obj = {
...item,
children: arr
};
newTreeData.push(obj)
}
```
### 二、关键字高亮
**功能要求:**
在模糊搜索得到的新树状表格中,将匹配到的关键字高亮。
**实现重点:**
1. 匹配关键字
2. 替换关键字为带有标签的关键字
3. 给标签添加样式
**方法封装:**
```js
hightLightText(text) {
if (text) {
const reg = new RegExp( this.inputValue, 'gi')// 动态正则表达式
return text.replace(reg, `<span style="color: #1F5FB1;">${this.inputValue}</span>`)// 使用replace替换
}
}
```
**页面渲染:**
```js
<template v-slot:name="record">
<span v-html="hightLightText(record.name)"></span>
</template>
```
### 三、动态设置树状表格的展开/折叠
**功能要求:**
树形表格初始状态默认是折叠的,当关键字搜索后,树形表格变为展开状态。
**实现重点:**
官方提供了`default-expand-all`属性控制树形表格的展开折叠,但是只有初始化的时候是生效的,而动态修改是无效的。
所以我们每修改一次,就需要让表格重新渲染一次。
**具体实现:**
```js
<v-table
ref="table"
v-if="refreshTable"
:loading="loading"
:dataSource="dataSource"
:columns="columns"
:defaultExpandAll="defaultExpandAll"
>
</v-table>
doSearch() {
this.refreshTable = false
this.$nextTick(()=> {
this.refreshTable = true
})
this.defaultExpandAll = true
}
```
上述代码中,当搜索事件doSearch执行时,通过变更refreshTable的值,来控制v-table组件(基于el-table二次封装的)的重新渲染。
注意,一定要加上nextTick(),或者延时器,否则,defaultExpandAll的更改会无效。推荐使用nextTick(),因为延时器会造成页面跳动。
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment