Asroads'Blog 君子不器
一些工作里常用的正则小技巧(持续更新)
发布于: 2023-07-16 更新于: 2024-03-02 分类于: other 阅读次数: 

众所周知编写程序或者有时候匹配搜索替换的时候,正则这个对于字符串来说特别好用,下面是我最近收集的一些常用的正则,后面会持续更新。便于日后工作中查阅,方便使用。

Cocos Creator 2.4.10 版本Typescript限制只能输入手机号

我们需要做的是创建一个新的脚本,并将以下代码复制进去。请注意需要将EditBox组件附着在同一节点上,并且在Cocos Creator编辑器里设置好cc.EditBox的引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const {ccclass, property} = cc._decorator;

@ccclass
export default class EditboxComponent extends cc.Component {
@property(cc.EditBox)
editbox: cc.EditBox = null;

onLoad() {
this.editbox.node.on('text-changed', this.onTextChanged, this);
}

onTextChanged(text: string) {
let phoneReg = /^1[3-9]\d{9}$/;
if (phoneReg.test(text)) {
// 用户输入的是有效的手机号,你可以根据需要进行后续操作
console.log("手机号格式正确");
} else {
// 用户输入的不是有效的手机号,你可以提示用户输入正确的手机号
console.log("请输入正确的手机号");
// 或者你可以清除用户输入的内容
this.editbox.string = '';
}
}
}

代码首先定义了一个cc.EditBox类型的属性editbox。你需要在Cocos Creator的属性检查器中设置这个属性,将EditBox组件关联到这个属性上。

onLoad方法中,我们注册了一个text-changed事件的监听器。当用户在EditBox中输入内容时,就会触发这个事件,并调用onTextChanged方法。

onTextChanged方法中,我们使用正则表达式来检查用户输入的内容是否符合手机号的模式。如果是,你可以根据需要进行后续操作。如果不是,你可以提示用户输入正确的手机号,或者清除用户输入的内容。

正则匹配 “inlineSpriteFrames”: {} 其中{}中间是非空内容

这个需求,主要是来源于小游戏中我需要对,小游戏平台的Assets Bundle 的meta 文件进行全局替换。下面的JavaScript正则表达式,这个表达式使用了负向预查的方式,确保匹配的字符串中不包含只有空白字符的情况。

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
function checkContent(s) {
var pattern = /"inlineSpriteFrames"\s*:\s*\{(?! *\})[^}]*\}/s;
var match = s.match(pattern);
if (match) {
return match[0];
} else {
return null;
}
}

// 测试有内容的字符串
var s = `"inlineSpriteFrames": {
"wechatgame": false,
"jkw-game": false,
"ios": false,
"web-mobile": false,
"android": false,
"bytedance": false
}`;
console.log(checkContent(s));

// 测试没有内容的字符串
s = `"inlineSpriteFrames": {}`;
console.log(checkContent(s)); // null

在这个表达式中,(?! *\}) 是一个负向预查,它会匹配到那些后面不是只有空白字符和 } 的位置。[^}]* 会匹配到任何不是 } 的字符,/s. 能够匹配到包括换行在内的任何字符。

拓展如果是可以匹配{} 内可以为空的内容

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
function checkContent(s) {
var pattern = /"inlineSpriteFrames"\s*:\s*\{[^}]*\S+[^}]*\}/s;
var match = s.match(pattern);
if (match) {
return match[0];
} else {
return null;
}
}

// 测试有内容的字符串
var s = `"inlineSpriteFrames": {
"wechatgame": false,
"jkw-game": false,
"ios": false,
"web-mobile": false,
"android": false,
"bytedance": false
}`;
console.log(checkContent(s));

// 测试没有内容的字符串
s = `"inlineSpriteFrames": {}`;
console.log(checkContent(s)); // null

在这个 JavaScript 函数中,我们使用了类似的正则表达式。/s 标记让 . 能够匹配换行符。我们使用了 \s* 来匹配任意数量的空格,[^}]*\S+[^}]* 来确保在 {} 中至少有一个非空白字符。

然后,我们测试了两个字符串,一个有内容的和一个没有内容的,以检验我们的函数是否能正确区分这两种情况。

注意,这样的情况没有处理多行的情况

获取文件路径里最后的名字:

取得最后一个斜线 / 后面的部分,但是去掉文件扩展名 .jpg.png。这种情况下,你可以使用以下正则表达式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let urls = [
"https://baidu.com/miniConfig/wx/image/shareCover=001.jpg",
"https://baidu.com/miniConfig/wx/image/shareCover=002.jpg",
"https://baidu.com/miniConfig/wx/image/shareCover=003.jpg",
"https://baidu.com/miniConfig/wx/image/test.jpg",
"https://baidu.com/miniConfig/wx/image/test.png"
];

let resultStrings: string[] = [];

urls.forEach(url => {
let match = url.match(/([^\/]+)(?=\.(jpg|png)$)/);
if (match) {
resultStrings.push(match[1]);
}
});

console.log(resultStrings); // 输出处理后的字符串数组

在这段代码中,用正则表达式 ([^\/]+)(?=\.(jpg|png)$) 来找出最后一个 / 后面的部分,但是并不包括文件扩展名 .jpg.png。然后把匹配的部分添加到 resultStrings 数组中。最后,打印出 resultStrings 数组,这就是需要的字符串列表。

当然如果仅仅是匹配 可以这样操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let urls = [
"https://baidu.com/miniConfig/wx/image/shareCover=001.jpg",
"https://baidu.com/miniConfig/wx/image/shareCover=002.jpg",
"https://baidu.com/miniConfig/wx/image/shareCover=003.jpg",
"https://baidu.com/miniConfig/wx/image/test.jpg",
"https://baidu.com/miniConfig/wx/image/test.png"
];

let regex = /[^\/]*(?=\.(jpg|png)$)/g;
let matchedStrings: string[] = [];

urls.forEach(url => {
let match = url.match(regex);
if (match) {
matchedStrings.push(match[0]);
}
});

console.log(matchedStrings); // 输出匹配的字符串数组

匹配 一个 * 或者多个*的正则

使用JavaScript的 RegExp.test()String.match() 方法来使用正则表达式。下面是两种方法的例子:

1. 使用 RegExp.test() 方法:

1
2
3
4
5
var regex = /\*+/g; 
var str = "我有一个*或者多个*的需求";
var hasAsterisks = regex.test(str);
console.log(hasAsterisks); // 如果str中包含一个或多个星号,将打印出true

RegExp.test() 方法会返回一个布尔值,如果字符串中含有与正则表达式匹配的部分,则返回 true,否则返回 false

2. 使用 String.match() 方法:

1
2
3
4
5
var regex = /\*+/g; 
var str = "我有一个*或者多个*的需求";
var matches = str.match(regex);
console.log(matches); // 如果str中包含一个或多个星号,将打印出包含这些星号的数组

String.match() 方法会返回一个数组,包含与正则表达式匹配的所有部分。如果没有找到匹配的部分,则返回 null

只能输入 26个字符和数字0-9

匹配长度为1-20的字符串,仅允许包含26个英文字母(大小写均可)和数字0-9:

可以使用以下的正则表达式来匹配长度为1-20的字符串,仅允许包含26个英文字母(大小写均可)和数字0-9:

1
^[A-Za-z0-9]{1,20}$

解释如下:

  • ^:表示匹配行的开始。
  • [A-Za-z0-9]:方括号内的内容表示一个字符集,允许的字符包括大写字母A-Z,小写字母a-z以及数字0-9。
  • {1,20}:表示前面的字符集可以重复出现1次到20次。
  • $:表示匹配行的结束。

在Cocos Creator中使用正则表达式限制输入框的内容,需要使用Typescript来编写一个组件。这个组件监听输入框的文本改变事件,并使用正则表达式来检查新的文本是否符合要求。这个过程可以如下实现:

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
const {ccclass, property} = cc._decorator;

@ccclass
export class LimitComponent extends cc.Component {

@property(cc.EditBox)
editBox: cc.EditBox = null;

// 正则表达式
private regex: RegExp = new RegExp("^[A-Za-z0-9]{1,20}$");

// 当编辑框文本改变时
onTextChanged(text: string, editBox: cc.EditBox, customEventData: string) {
if (!this.regex.test(text)) {
// 如果新的文本不符合要求,将其设为之前的文本
editBox.string = editBox.string;
cc.log("输入内容不符合要求");
}
}

start () {
// 初始化,为编辑框添加文本改变事件的监听
this.editBox.node.on('text-changed', this.onTextChanged, this);
}
}

请注意,上述代码需要将cc.EditBox组件添加到节点中,并将该节点挂载到editBox属性中。

匹配错误行数

1
subpackages\/main\/game\.js:\d+:(\d+)
1
2
3
4
5
6
7
8
9
const errorMessage = "MiniProgramError Cannot read property 'unlock' of null TypeError: Cannot read property 'unlock' of null at e.checkSysUnlock (http://127.0.0.1:48621/game/subpackages/main/game.js:1:6980332) at e.init (http://127.0.0.1:48621/game/subpackages/main/game.js:1:6973789) at e.onLoad (http://127.0.0.1:48621/game/subpackages/main/game.js:1:7425613) at http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:691203 at r._invoke (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:463172) at r.invoke (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:462491) at r.activateNode (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:692769) at r._activate (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:327724) at 70.cc.Director.runSceneImmediate (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:281991) at 70.cc.Director.<anonymous> (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:282303)";

const regex = /subpackages\/main\/game\.js:\d+:(\d+)/;
const match = errorMessage.match(regex);

if (match) {
const columnNumber = match[1];
console.log(columnNumber); // 输出: 6980332
}

或者:

1
2
3
4
5
6
7
8
const errorMessage = "MiniProgramError Cannot read property 'unlock' of null TypeError: Cannot read property 'unlock' of null at e.checkSysUnlock (http://127.0.0.1:48621/game/subpackages/main/game.js:1:6980332) at e.init (http://127.0.0.1:48621/game/subpackages/main/game.js:1:6973789) at e.onLoad (http://127.0.0.1:48621/game/subpackages/main/game.js:1:7425613) at http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:691203 at r._invoke (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:463172) at r.invoke (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:462491) at r.activateNode (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:692769) at r._activate (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:327724) at 70.cc.Director.runSceneImmediate (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:281991) at 70.cc.Director.<anonymous> (http://127.0.0.1:48621/game/__context__/__plugin__/wx7095f7fa398a2f30/plugin.js:5:282303)";

const regex = /subpackages\/main\/game\.js:\d+:(\d+)/g;
const matches = [...errorMessage.matchAll(regex)];

const extractedMatches = matches.map(match => match[1]);
console.log(extractedMatches); // 输出提取出的内容数组

匹配特定的 TypeScript 或 JavaScript 导入语句,

如 import { GConfig } from ‘../../../../config/GameConfig’;,你可以使用以下模式:

1
/import { GConfig } from '.*config/GameConfig';?/
--- 本文结束 The End ---