正则

案例1: 将下划线命名批量改成小驼峰命名

场景

Sql字段通常下划线命名,Java的dto通常小驼峰命名。示例如下:

1
2
3
hello_world
转换为
helloWorld

旨在实现如下校验目标:

  1. 若 “_小写字母”,则替换为“大写字母”

方法

1.若 “_小写字母”,则替换为“大写字母”
  • 遍历欲替换的字符串列表
  • 对每一项字符串替换
1
2
3
4
5
6
7
8
9
10
11
12
13
const source=[
"wholePreAssets",
"wire_gsm_optimize_rate",
];
const result=[];
 
for(let item of source){
const str=item.replace(/_[a-z]/g,function(word){
return word.substring(1).toUpperCase();
});
result.push(str);
}
return result;
2.将字符串/变量替换为abc
1
2
const str = str.replace(new RegExp(name, 'gm'), 'abc'); // 全局替换
const str = str.replace(name, 'abc'); // 只替换第一个

正则整理

  1. 获取正则匹配值并替换: str.replace(regex, function(word){ });
    • word 即为 正则匹配值
  2. js中没有replaceAll方法,要想全局替换,可借助正则表达式

案例2: “伪SQL表达式”简单校验

场景

如下” 伪SQL表达式”,其中,数字序号代表具体的表达式(eg. name = 20),and or 小括号等是sql语句常用连接符。

1
1 and 2 and (3 or 4) and (5 or 6 or 7)

旨在实现如下校验目标:

  1. 小括号配对校验
  2. 将所有数字取出

附探讨目标:最初设计“伪SQL表达式”如下,以#num代表具体表达式。(毫无必要,已废弃)

1
#1 and #2 and (#3 or #4) and (#5 or #6 or #7)

探讨目标:

  1. #号后面必须紧跟数字
  2. 数字之前必须有#号

方法

1.取出所有数字
1
2
const patten = /\d+/g;
const numList = str.match(patten) || [];
3.#号后面必须紧跟数字
1
2
const patten = /#\D+/;
const isNotNumber = patten.test(str);
4.数字之前必须有#号
1
2
3
4
5
6
const patten = /#?(?=\d+)\d+/g;
const numList =str.match(patten) || []; // [1,#2,#3,4,5,#6]
const list = numList.filter(o => o.indexOf('#') === -1);
if (list && list.length > 0) {
// 无#的数字列表
}
2.校验小括号是否配对
  • 准备一个结构
  • 遍历字符串中所有字符
  • 如果字符为左括号,则字符入栈
  • 如果字符为右括号,则出栈
  • 如果出栈字符为空,则说明该右括号无左括号对应,返回false
  • 如果出栈字符与右括号所对应的左括号不一致,则说明右括号对应左括号出错,返回false
  • 如果遍历完成后,栈的长度非空,则说明左右括号不一一配对,返回false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// 栈
class Stack {
constructor() {
this.dataStore = [];
this.top = 0;
}
push(element) {
this.dataStore[this.top++] = element;
}
pop() {
return this.dataStore[--this.top];
}
peek() {
if (this.top > 0) {
return this.dataStore[this.top - 1];
}
return 'Empty';
}
length() {
return this.top;
}
clear() {
delete this.dataStore;
this.dataStore = [];
this.top = 0;
}
}
// 括号常量
const PARENTHESES = {
left: ['(', '{', '['],
right: [')', '}', ']'],
};

/**
* 校验括号是否配对
* @param testStr 待校验字符串
* @returns {boolean} true则括号配对,false则括号不配对
*/
const checkParentheses = (testStr) => {
const testCharacterList = testStr.split('');
const stack = new Stack();

for (let i = 0; i < testCharacterList.length; i++) {
const character = testCharacterList[i];
const idxLeft = PARENTHESES.left.indexOf(character);
if (idxLeft > -1) {
stack.push(character);
}
const idxRight = PARENTHESES.right.indexOf(character);
if (idxRight > -1) {
const outCharacter = stack.pop();
if (!outCharacter) {
return false;
}
if (outCharacter !== PARENTHESES.left[idxRight]) {
return false;
}
}
}
return !stack.length();
};

正则整理

  1. 全局匹配数字: /\d+/g
  2. 全局匹配“数字、#数字两种类型” : /#?(?=\d+)\d+/g
    • (?=\d+) 获取数字前的位置Pos
    • #? 位置Pos前有“0或1个#号”
    • \d+ 位置Pos后有数字
  3. “特殊符号#后不是数字”:/#\D+/
  4. 获取字符串内指定值,或正则表达式匹配值: str.match(regex / searchvalue)
  5. 检测字符串是否匹配正则模式: regex.test(str)
-------------Keep It Simple Stupid-------------
0%