当前位置: 首页 > news >正文

正则表达式详解

这里写目录标题

  • 一、基本概念
    • 1.基本语法
    • 2.修饰符
    • 3.方括号
    • 4.元字符
    • 5.量词
  • 二、结构
    • 1.匹配模式
    • 2.字符组
    • 3.量词
    • 4.贪婪匹配和惰性匹配
    • 5.多选分支
    • 6.匹配模式关键词
  • 三、位置
    • 1.位置锚点
    • 2.分组与引用
      • 1.分组与编号
      • 2.不保存子组
      • 3.括号嵌套
      • 4.命名捕获组
      • 5.引用捕获组
    • 3.回溯匹配
  • 四、对象方法
    • 1.test 方法
    • 2.exec 方法
      • **逐步匹配**
      • **捕获组与子匹配项**
      • 命名捕获组
      • lastIndex 属性
      • 方法的比较
      • 常见错误
    • 3.match 方法
      • **无全局标志**
      • **带全局标志**
      • **特殊情况**
    • 4.matchAll 方法
      • **特殊情况**
      • **适用场景**
    • 5.总结
  • 五、常见应用
    • **1.合法IP地址**
    • **2.合法邮箱**


代码,是前端工程师的“武器”,也是他们的“面包和黄油”。


一、基本概念

正则表达式(regular expression)描述了字符的模式对象。

1.基本语法

var patt=new RegExp(pattern,modifiers);
var patt=/pattern/modifiers;// 参数
.pattern 模式,描述了表达式的模式
.modifiers 修饰符,检索是否是全局,区分大小写等

2.修饰符

修饰符用于执行区分大小写和全局匹配

修饰符描述
i执行对大小写不敏感的匹配。
g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m执行多行匹配。

3.方括号

方括号用于查找某个范围内的字符

表达式描述
[abc]查找方括号之间的任何字符。
[^abc]查找任何不在方括号之间的字符。
[0-9]查找任何从 0 至 9 的数字。
[a-z]查找任何从小写 a 到小写 z 的字符。
[A-Z]查找任何从大写 A 到大写 Z 的字符。
[A-z]查找任何从大写 A 到小写 z 的字符。
[adgk]查找给定集合内的任何字符。
[^adgk]查找给定集合外的任何字符。
(redblue

4.元字符

元字符(Metacharacter)是拥有特殊含义的字符:

元字符描述
.查找单个字符,除了换行和行结束符。
\w查找数字、字母及下划线。
\W查找非单词字符。
\d查找数字。
\D查找非数字字符。
\s查找空白字符。
\S查找非空白字符。
\b匹配单词边界。
\B匹配非单词边界。
\0查找 NULL 字符。
\n查找换行符。
\f查找换页符。
\r查找回车符。
\t查找制表符。
\v查找垂直制表符。
\xxx查找以八进制数 xxx 规定的字符。
\xdd查找以十六进制数 dd 规定的字符。
\uxxxx查找以十六进制数 xxxx 规定的 Unicode 字符。

5.量词

量词描述
n+匹配任何包含至少一个 n 的字符串。
n*匹配任何包含零个或多个 n 的字符串。
n?匹配任何包含零个或一个 n 的字符串。
n{X}匹配包含 X 个 n 的序列的字符串。
n{X,}X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。
n{X,Y}X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。
n$匹配任何结尾为 n 的字符串。
^n匹配任何开头为 n 的字符串。
?=n匹配任何其后紧接指定字符串 n 的字符串。
?!n匹配任何其后没有紧接指定字符串 n 的字符串。
^                   from the start of the input
(?=.*\d)            assert one or more digits are present
(?=.*[a-z])         assert lowercase letters
(?=.*[A-Z])         assert uppercase letters
(?=.*[^a-zA-Z0-9])  assert one or more characters which are NOT alphanumeric
(?!.*\s)            assert one or more whitespace characters

二、结构

1.匹配模式

精确匹配应用比较局限,匹配数据比较少;模糊匹配结果可能性更多,能够满足更多场景

var regex = /hello/; // 精确匹配
regex = /^hello$/; // 精确匹配 + 完全匹配
regex = /hel{2}o/; // 模糊匹配 + 横向模糊(重复)
regex = /hel[lk]o/; // 模糊匹配 + 纵向模糊(该位置有多种可能)([lk]只占据一个位置)
console.log( regex.test("hello") );

2.字符组

字符组归纳了一连串的字符或者枚举值

// 正向字符组
12345可以表示成[1-5],该规范默认会被识别成字符组([-15]就不会被识别成字符组)
bcdefg可以表示成[b-g]// 取反字符组
[^1-5]表示除了12345以外的字符// 字符组简写
数字:\d 表示 [0-9];\D 表示 [^0-9]
单词(数字、字母、下划线):\w 表示 [a-zA-Z0-9_];\W 表示 [^a-zA-Z0-9_]
空白符(空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符):
\s 表示 [ \t\v\n\r\f];\S 表示 [^ \t\v\n\r\f]; // 注意空格
. 表示 任意字符

3.量词

假设匹配数量是num

{m} 表示 num = m
{m,} 表示 m <= num
{m, n} 表示 m <= num <= m
? 表示 0 <= num <= 1
+ 表示 1 <= num
* 表示 0 <= num

4.贪婪匹配和惰性匹配

默认贪婪匹配,量词后加?表示惰性匹配
{m, n} + 贪婪匹配 === n
{m, n}? + 惰性匹配 === m

var regex = /\d{2,5}/; // 12345
regex = /\d{2,5}?/; // 12
const string = "123456";
console.log(string.match(regex) );

5.多选分支

var regex = /red|color/g;
var string = "red yellow color"; // 示范值 [red, color]
string = "redcolor"; // red 匹配到了不会再选择领一个分支;分支也是默认惰性
console.log(string.match(regex) );

6.匹配模式关键词

g 表示 全局匹配,类似于贪婪匹配,匹配到一个满足条件的,不会停止,继续往下匹配
i 表示 忽略大小写
m 表示 多行,针对有\n换行符的字符串

三、位置

在这里插入图片描述

1.位置锚点

^ 表示 匹配开头,在多行匹配中匹配行开头
$ 表示 匹配结尾,在多行匹配中匹配行结尾
\b 表示 单词边界(单词左右两边和非单词的位置)
\B 表示 非单词边界(单词内部的字符之间的位置)
(?=key) 表示 key的一个子模式,表示key前面的那个位置
(?!key) 表示 key的一个子模式,表示不是key前面的那个位置
(?<=key) 表示 key的一个子模式,表示key后面的那个位置
(?<!key) 表示 key的一个子模式,表示不是key后面的那个位置

案例

// 空格匹配
console.log("hello".replace(/^|$/g, '#')); // #hello#
// 多行匹配
console.log("hello\nworld".replace(/^|$/gm, '#')); // #hello##world# m表示多行
// 单词边界
"world+".replace(/\b/g, '#') // #world#+ 注意头部和尾部和单词之间也算一个边界
// o前面的位置
"world+".replace(/(?=o)/g, '#') // w#orld+
// o后面的位置
"world+".replace(/(?<=o)/g, '#') // wo#rld+

2.分组与引用

括号在正则中的功能就是用于分组(字符的集合)。简单来理解就是,由多个元字符组成某个部分,应该被看成一个整体的时候,可以用括号括起来表示一个整体,这是括号的一个重要功能。其实用括号括起来还有另外一个作用,那就是“复用”。

/1(1|2)/g.test("12") // true
"121213".match(/1(1|2)/g) // [12, 12]
"121213".match(/1(1|2)+/g) // [1212] +号会让他变成贪婪匹配

1.分组与编号

括号在正则中可以用于分组,被括号括起来的部分“子表达式”会被保存成一个子组。

那分组和编号的规则是怎样的呢?其实很简单,用一句话来说就是,第几个括号就是第几个分组。
在这里插入图片描述

2.不保存子组

在括号里面的会保存成子组,但有些情况下,你可能只想用括号将某些部分看成一个整体,后续不用再用它,类似这种情况,在实际使用时,是没必要保存子组的。这时我们可以在括号里面使用 ?: 不保存子组。

如果正则中出现了括号,那么我们就认为,这个子表达式在后续可能会再次被引用,所以不保存子组可以提高正则的性能。
在这里插入图片描述

const regex = /(?:\d{4})-(\d{2})-(\d{2})/;
const str = "1990-12-17";
const match = regex.exec(str);if (match !== null) {console.log(`Month: ${match[1]}`);console.log(`Day: ${match[2]}`);
} else {console.log("No date found.");
}

在这个例子中,年份的捕获组被转换为一个非捕获组,因此它不会出现在 match 数组中。这样,match[1] 直接引用月份,而不是年份。

3.括号嵌套

在括号嵌套的情况里,我们要看某个括号里面的内容是第几个分组怎么办?只需要数左括号(开括号)是第几个,就可以确定是第几个子组。
在这里插入图片描述

日期分组编号是 1,时间分组编号是 5,年月日对应的分组编号分别是 2,3,4,时分秒的分组编号分别是 6,7,8。

// 从左到右读取,碰到括号进入括号,再从左到右读取
"123".replace(/(\d(\d(\d)))/, "$1-$2-$3") // 123-12-3

4.命名捕获组

在一些编程语言中还提供了命名分组,命名分组格式为(?<分组名>正则)。

const regex = /(?<group1>\w+)\s+(?<group2>\w+)/;
const result = regex.exec("Hello World");console.log(result.groups.group1); // 输出 "Hello"
console.log(result.groups.group2); // 输出 "World"

5.引用捕获组

在知道了分组引用的编号 (number)后,大部分情况下,就可以使用 “反斜扛 + 编号”,即 \number 的方式来进行引用,而 JavaScript 中是通过$编号来引用的,如$1。

// 正则中的分组引用 === \index 如\1, \2
"1231213".match(/(12)\d\1/g) // 12312   \1 表示分组变量 (12)
// 替换变量 $ + index
"12123".replace(/(12)(123)/g, "$2$1") // $1 表示分组变量 (12) $2 表示分组变量 (123)// 分组全部替换
// $1 === 123; $2 === 12
// str被reg匹配为123 12 123 12,剩余字符串为‘’,直接替换
str = '123 12 123 12'
reg = /(123) (12) \1 \2/g
str.replace(reg, '$2-$1')
// return '12-123'// 分组部分替换
// str被reg匹配为12 123,剩余字符串为'124 {regStr} 12'
// 12-123替换regStr,最终为'124 12-123 12'
str = '124 12 123 12'
reg = /(123)?(12) \1/g
str.replace(reg, '$2-$1')
// return '124 12-123 12'

3.回溯匹配

"12223".match(/12{1,3}3/) // 匹配5步就结束了
// 无回溯;匹配1,匹配2子模式,匹配3,顺利结束"1223".match(/12{1,3}3/) // 1223
// 匹配到122以后,第4步在第四个位置,依然匹配字符串2,发现是3,于是回到上一步的状态,结束2{1,3}子模式
// 第5步回溯
// 第6步开始对3的匹配,在第四个位置匹配3,找到了,结束字符串3的匹配

四、对象方法

方法描述
compile在 1.5 版本中已废弃。 编译正则表达式。
exec检索字符串中指定的值。返回找到的值,并确定其位置。
test检索字符串中指定的值。返回 true 或 false。
toString返回正则表达式的字符串。

支持正则表达式的 String 对象的方法

方法描述FFIE
search检索与正则表达式相匹配的值。14
match找到一个或多个正则表达式的匹配。14
replace替换与正则表达式匹配的子串。14
split把字符串分割为字符串数组。14

RegExp 对象属性

属性描述
constructor返回一个函数,该函数是一个创建 RegExp 对象的原型。
global判断是否设置了 “g” 修饰符
ignoreCase判断是否设置了 “i” 修饰符
lastIndex用于规定下次匹配的起始位置
multiline判断是否设置了 “m” 修饰符
source返回正则表达式的匹配模式

1.test 方法

test()方法搜索字符串指定的值,根据结果并返回真或假。

var patt1=new RegExp("e");
patt1.test("The best things in life are free")var str = 'runoob';
var patt1 = new RegExp('\\w', 'g'); // 有转义作为正则表达式处理
var patt2 = new RegExp('\w', 'g');  // 无转义作为字符串处理
var patt3 =/\w+/g;  // 与 patt1 效果相同patt1.test(str) // 输出 true
patt2.test(str) // 输出 false
patt3.test(str) // 输出 true

2.exec 方法

exec() 方法用于在字符串中执行搜索匹配,它接受一个字符串作为参数,并返回一个数组,该数组表示匹配的结果。如果没有找到匹配,则返回 null。

let match = regExp.exec(str)

其中,regExp是一个正则表达式对象,str是要在其中执行搜索的字符串参数。

返回值结构

  • [0]:匹配到的整个字符串

  • [1] 及其他(从索引1开始):捕获组的内容(如果正则表达式使用了捕获组,如 ())

  • index:匹配的开始位置(在原字符串中的起始索引)

  • input:被搜索的原字符串

  • groups:一个对象,包含所有命名捕获组的匹配内容(如果有使用命名捕获组)

使用exec方法可以执行有限次数的全局搜索,并每次返回一个匹配项。下次执行时,它会从上一次匹配项的后面继续搜索。

逐步匹配

exec()方法的一个强大之处在于,它可以用于逐步匹配字符串中的多个匹配项。通过在一个循环中反复调用exec(),我们可以逐个处理每个匹配项,直到没有更多的匹配项为止。

const regex = /ab*/g;
const str = "abbcdefabhijkab";
let match;while ((match = regex.exec(str))) {console.log(`匹配到的文本:${match[0]}`);console.log(`匹配项在字符串中的起始位置:${match.index}`);
}// 输出结果:
// 匹配到的文本:abb
// 匹配项在字符串中的起始位置:0
// 匹配到的文本:ab
// 匹配项在字符串中的起始位置:7
// 匹配到的文本:ab
// 匹配项在字符串中的起始位置:14

捕获组与子匹配项

捕获组(Capturing Groups)通过括号 () 来定义,它可以匹配并提取部分字符串。每个括号内的表达式都是一个捕获组,可以捕获与之匹配的文本。

这些捕获组的结果将作为返回数组的后续元素(从索引1开始)出现。这使得我们可以轻松地访问和处理匹配项中的子部分。

let regex = /(\d+)\s(\w+)/;  // 匹配:数字 空格 字母组合
let result = regex.exec("123 abc");
console.log(result);// 输出结果
['123 abc',  // 整个匹配的字符串'123',      // 捕获组 1:数字部分'abc',      // 捕获组 2:字母部分index: 0,   // 匹配开始的索引input: '123 abc'
]

命名捕获组

**命名捕获组的优势:**命名捕获组(使用 (?pattern) 语法)可以让匹配结果更具可读性,特别是当你需要提取多个不同的部分时。

let regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
let result = regex.exec("2023-09-24");
console.log(result);// 输出结果:
['2023-09-24',   // 匹配到的整个字符串'2023',         // 第一个捕获组:年份'09',           // 第二个捕获组:月份'24',           // 第三个捕获组:日期index: 0,       // 匹配的起始索引input: '2023-09-24',  // 被搜索的字符串groups: {       // 命名捕获组year: '2023',month: '09',day: '24'}
]

通过 groups 属性,你可以更方便地获取并使用这些命名捕获的结果,而不需要依赖捕获组的顺序。

全局匹配与lastIndex属性

当正则表达式包含全局标志(g)时,exec()方法的行为会发生变化。它将从lastIndex属性指定的位置开始搜索匹配项,并在找到匹配项后更新lastIndex的值。这使得我们可以在一个循环中逐步处理字符串中的所有匹配项。

let regex = /\d+/g;
let str = "123 456 789";
let result;while ((result = regex.exec(str)) !== null) {console.log(result);
}// 输出结果
[ '123', index: 0, input: '123 456 789' ]
[ '456', index: 4, input: '123 456 789' ]
[ '789', index: 8, input: '123 456 789' ]

每次调用 exec(),它会返回下一个匹配的结果,直到返回 null,表示没有更多匹配。

lastIndex 属性

在全局匹配模式下,正则表达式对象的 lastIndex 属性会记录下次匹配开始的位置。每次匹配后,lastIndex 会更新,帮助 exec() 从上次结束的位置继续匹配。

let regex = /\d+/g;
let str = "123 456 789";
let result = regex.exec(str);console.log(result);  // 匹配 123
console.log(regex.lastIndex);  // 输出 3result = regex.exec(str);
console.log(result);  // 匹配 456
console.log(regex.lastIndex);  // 输出 7

方法的比较

  • **test():**返回布尔值,表示正则表达式是否匹配字符串。

  • **match():**如果是非全局正则表达式,它与 exec() 类似,但全局正则时,它一次性返回所有匹配项。

  • **exec():**可以返回详细的匹配结果,包括捕获组和匹配位置。

let regex = /\d+/g;
let str = "123 456 789";// 使用 exec() 逐步匹配
let result;
while ((result = regex.exec(str)) !== null) {console.log(result[0]);  // 依次输出 123, 456, 789
}// 使用 match() 一次性匹配
let matches = str.match(regex);
console.log(matches);  // ['123', '456', '789']

常见错误

  • 忘记考虑全局标志和lastIndex:当使用全局正则时,exec() 会记住上次匹配结束的位置。如果不注意,可能导致跳过某些匹配。

  • 忽略捕获组:如果想提取特定内容但没有使用捕获组,匹配结果中就不会包含这些信息。

  • 没有处理命名捕获组:如果正则中使用了命名捕获组,但未正确访问 groups 属性,就无法获取命名捕获结果。

3.match 方法

match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。

stringObject.match(searchvalue)
stringObject.match(regexp)
参数描述
searchvalue必需。规定要检索的字符串值。
regexp必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象。
// 参数为searchvalue时:
var str="Hello world!"
str.match("world")  // ["world", index: 6, input: "Hello world!", groups: undefined]
str.match("World")  // null
str.match("worlld")  // null
str.match("world!") 
// 返回结果
["world!", index: 6, input: "Hello world!", groups: undefined
]// 参数为正则表达式时:
var str=" mm -4193 1 with words"
str.match(/\d+/g) // ["4193", "1"]
str.match(/\d+/)  
// 未加全局时:
["4193", index: 5, input: " mm -4193 1 with words", groups: undefined
]var str2="-6754 uuuid" //获取带符号的整数
str2.match(/^(-|\+)?\d+/) 
// 返回结果
["-6754", "-", index: 0, input: "-6754 uuuid", groups: undefined
]

无全局标志

当正则表达式不带 g 标志时,match() 只返回第一个匹配的字符串和其他相关的匹配信息。包括:

  • **groups:**一个捕获组对象或undefined(如果没有定义命名捕获组)

  • **index:**匹配的结果的开始索引位置

  • **input:**搜索的字符串

const text = "I have 2 cats and 3 dogs.";
const result = text.match(/(\d+)/);console.log(result); 
// 输出: ["2", "2"]
  • result[0]:整个匹配(2)。

  • result[1]:捕获组中的匹配(2)。

带全局标志

使用 g 标志后,match() 会返回字符串与正则表达式匹配的所有结果组成的数组,如果没有匹配的字符串则返回null,但不会返回捕获组。

const text = "I have 2 cats and 3 dogs.";
const result = text.match(/\d+/g);console.log(result);  
// 输出: ["2", "3"]

此时 match() 返回一个数组,包含了所有数字的匹配项 [“2”, “3”]。

特殊情况

**无匹配项:**如果正则表达式没有匹配到任何结果,match() 会返回 null。

const result = "hello".match(/\d+/);
console.log(result);  // 输出: null

**无全局标志但有捕获组:**当没有 g 标志且有捕获组时,match() 不仅返回整个匹配,还会返回所有捕获组的匹配。

const text = "The price is $100";
const result = text.match(/(\$\d+)/);
console.log(result);  
// 输出: ["$100", "$100"]
const str = 'Hello JavaScript'
str.match()  // [""]
str.match(/JS/) // null
str.match(/JavaScript/g)  // ["JavaScript"]
str.match(/JavaScript/)
// 返回结果
[0: "JavaScript", groups: undefined, index: 6, input: "Hello JavaScript"
]
str.match(/(?<J>Java)(?<S>Script)/)
// 返回结果
[0: "JavaScript", 1: "Java", 2: "Script", groups: { J: "Java", S: "Script" }, index: 6, input: "Hello JavaScript"
]

4.matchAll 方法

matchAll() 方法返回一个包含所有匹配正则表达式的结果及其分组捕获组的迭代器。

str.matchAll(reg)

**reg:**正则表达式对象。如果不是正则表达式则会使用new RegExp(obj)隐式转换为正则表达式。表达式必须设置为 g (全局模式)否则会报错

**返回值:**一个迭代器,可以使用for…of…,数组新增的扩展符(…)或Array.from()实现功能。

const str = 'hello javascript hello css'
console.log(...str.matchAll(/hello/g))
// [0: "hello", groups: undefined, index: 0, input: "hello javascript hello css"]
// [0: "hello", groups: undefined, index: 17, input: "hello javascript hello css"]// 0: "hello"  匹配的字符串,如果有使用分组会在后面依次列出来
// groups: undefined  没有使用命名捕获组会返回undefined,否则会返回包含命名捕获组的对象
// index: 0  匹配的结果在当前字符串位置开始的索引
// input: "hello javascript hello css" 当前字符串

特殊情况

**没有全局标志 g:**如果正则表达式没有 g 标志,matchAll() 会抛出错误。

const text = "I have 2 cats and 3 dogs.";
const result = text.matchAll(/\d+/);  // 错误:没有 g 标志

**支持捕获组:**即使在没有 g 标志时,matchAll() 依然会返回所有捕获组。

特性match()matchAll()
返回类型数组(或ull)迭代器(包含所有匹配及捕获组)
是否支持全局匹配需要g标志才能去哪聚匹配始终全局匹配,不需要g
捕获组支持仅在无g标志时返回捕获组始终返回所有捕获组
返回多个结果仅在g标志时返回多个匹配项始终返回多个匹配项和捕获组
返回的结果如何处理只返回匹配项,捕获组不一定返回返回匹配的所有详细信息,包含索引、捕获组等
使用场景简单的正则匹配,适合单个结果或少量结果复杂匹配,特别是需要捕获组和详细信息时

适用场景

match() 适用场景:

  • 当只需要找到第一个匹配结果或在简单的场景下查找所有匹配项时使用。

  • 不关心捕获组的详细信息,只关心匹配的值。

matchAll() 适用场景:

  • 当需要获取所有匹配项的详细信息,包括索引、捕获组时,matchAll() 更加合适。

  • 在涉及多个捕获组的复杂匹配场景中,使用 matchAll() 可以获得更多控制和信息。

5.总结

  • match() 用于简单匹配,它在没有 g 标志时返回第一个匹配及捕获组,而在有 g 标志时返回所有匹配项,但不包含捕获组。

  • matchAll() 提供了更强大的功能,返回一个包含所有匹配和捕获组的迭代器,适用于复杂匹配场景,特别是在处理多个捕获组时表现出色。

五、常见应用

1.合法IP地址

ip地址合法的标准是:a.b.c.d 是0255之间的十进制整数。IP地址是指互联网协议地址,是一个32位的二进制数,通常被分割为4个“8位二进制数”。IP地址通常用“点分十进制”,其中a.b.c.d应是0255之间的十进制整数。

iPv4的ip地址都是(1255).(0255).(0255).(0255)的格式。

A类的IP地址范围为0.0.0.0-127.255.255.255,B类的IP地址范围为128.0.0.0-191.255.255.255,C类的IP地址范围为192.0.0.0-223.255.255.255。

判断IP合法性:

1、IP地址是4个3位数用"."隔开的字串;

2、其中每个3位数都一定在0~255(含)之间,否则为非法;

3、IP地址也有内网与公网之分。

2.合法邮箱

邮箱的基本格式为:“用户名@域名”,用户名部分以字母和数字开头,可以包含字母、数字、点号(.)、下划线(_)和连字符(-),而域名部分可以包含字母、数字、点号(.)和连字符(-)。此外,域名部分还必须包含至少一个点号,以区分顶级域名和次级域名。如果邮箱的格式不符合这些规则,则可以判断邮箱不合法。

1、是否合法IP地址:
pattern:/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/,2.是否手机号码或者固话
pattern:/^((0\d{2,3}-\d{7,8})|(1[34578]\d{9}))$/,3. 是否身份证号码
pattern:/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,4.是否邮箱
pattern:/^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$/,5.整数填写
pattern:/^-?[1-9]\d*$/,6.正整数填写
pattern:/^[1-9]\d*$/,7.小写字母
pattern:/^[a-z]+$/,8.大写字母
pattern:/^[A-Z]+$/,9.大小写混合
pattern:/^[A-Za-z]+$/,10.多个8位数字格式(yyyyMMdd)并以逗号隔开
pattern:/^\d{8}(\,\d{8})*$/,11.数字加英文,不包含特殊字符
pattern:/^[a-zA-Z0-9]+$/,12.前两位是数字后一位是英文
pattern:/^\d{2}[a-zA-Z]+$/,13.密码校验(6-20位英文字母、数字或者符号(除空格),且字母、数字和标点符号至少包含两种)
pattern:/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$)([^\u4e00-\u9fa5\s]){6,20}$/,// 密码的强度必须是包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间。
pattern: /^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$/14.中文校验
pattern:/^[\u0391-\uFFE5A-Za-z]+$/,15.中文汉字校验
pattern:/^[/u4e00-/u9fa5]+$/,

参考:https://blog.csdn.net/maggie_live/article/details/85045868
https://blog.csdn.net/PersonalM/article/details/103783278

validator.js文件中常见的验证方法

1、是否合法IP地址
export function validateIP(rule, value,callback) {if(value==''||value==undefined||value==null){callback();}else {const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;if ((!reg.test(value)) && value != '') {callback(new Error('请输入正确的IP地址'));} else {callback();}}
}2、是否手机号码或者固话
export function validatePhoneTwo(rule, value, callback) {const reg = /^((0\d{2,3}-\d{7,8})|(1[34578]\d{9}))$/;;if (value == '' || value == undefined || value == null) {callback();} else {if ((!reg.test(value)) && value != '') {callback(new Error('请输入正确的电话号码或者固话号码'));} else {callback();}}
}3、是否固话
export function validateTelphone(rule, value,callback) {const reg =/0\d{2,3}-\d{7,8}/;if(value==''||value==undefined||value==null){callback();}else {if ((!reg.test(value)) && value != '') {callback(new Error('请输入正确的固定电话)'));} else {callback();}}
}4、是否手机号码
export function validatePhone(rule, value,callback) {const reg =/^[1][3-9][0-9]{9}$/;if(value==''||value==undefined||value==null){callback();}else {if ((!reg.test(value)) && value != '') {callback(new Error('请输入正确的电话号码'));} else {callback();}}
}
5、是否身份证号码
export function validateIdNo(rule, value,callback) {const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;if(value==''||value==undefined||value==null){callback();}else {if ((!reg.test(value)) && value != '') {callback(new Error('请输入正确的身份证号码'));} else {callback();}}
}6、是否邮箱
export function validateEMail(rule, value,callback) {const reg =/^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$/;if(value==''||value==undefined||value==null){callback();}else{if (!reg.test(value)){callback(new Error('请输入正确的邮箱'));} else {callback();}}
}7、合法url
export function validateURL(url) {const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;return urlregex.test(url);
}8、验证内容是否包含英文数字以及下划线
export function isPassword(rule, value, callback) {const reg =/^[_a-zA-Z0-9]+$/;if(value==''||value==undefined||value==null){callback();} else {if (!reg.test(value)){callback(new Error('仅由英文字母,数字以及下划线组成'));} else {callback();}}
}9、自动检验数值的范围
export function checkMax20000(rule, value, callback) {if (value == '' || value == undefined || value == null) {callback();} else if (!Number(value)) {callback(new Error('请输入[1,20000]之间的数字'));} else if (value < 1 || value > 20000) {callback(new Error('请输入[1,20000]之间的数字'));} else {callback();}
}10、验证数字输入框最大数值
export function checkMaxVal(rule, value,callback) {if (value < 0 || value > 最大值) {callback(new Error('请输入[0,最大值]之间的数字'));} else {callback();}
}11、验证是否1-99之间
export function isOneToNinetyNine(rule, value, callback) {if (!value) {return callback(new Error('输入不可以为空'));}setTimeout(() => {if (!Number(value)) {callback(new Error('请输入正整数'));} else {const re = /^[1-9][0-9]{0,1}$/;const rsCheck = re.test(value);if (!rsCheck) {callback(new Error('请输入正整数,值为【1,99】'));} else {callback();}}}, 0);
}12、验证是否整数
export function isInteger(rule, value, callback) {if (!value) {return callback(new Error('输入不可以为空'));}setTimeout(() => {if (!Number(value)) {callback(new Error('请输入正整数'));} else {const re = /^[0-9]*[1-9][0-9]*$/;const rsCheck = re.test(value);if (!rsCheck) {callback(new Error('请输入正整数'));} else {callback();}}}, 0);
}13、验证是否整数,非必填
export function isIntegerNotMust(rule, value, callback) {if (!value) {callback();}setTimeout(() => {if (!Number(value)) {callback(new Error('请输入正整数'));} else {const re = /^[0-9]*[1-9][0-9]*$/;const rsCheck = re.test(value);if (!rsCheck) {callback(new Error('请输入正整数'));} else {callback();}}}, 1000);
}14、 验证是否是[0-1]的小数
export function isDecimal(rule, value, callback) {if (!value) {return callback(new Error('输入不可以为空'));}setTimeout(() => {if (!Number(value)) {callback(new Error('请输入[0,1]之间的数字'));} else {if (value < 0 || value > 1) {callback(new Error('请输入[0,1]之间的数字'));} else {callback();}}}, 100);
}15、 验证是否是[1-10]的小数,即不可以等于0
export function isBtnOneToTen(rule, value, callback) {if (typeof value == 'undefined') {return callback(new Error('输入不可以为空'));}setTimeout(() => {if (!Number(value)) {callback(new Error('请输入正整数,值为[1,10]'));} else {if (!(value == '1' || value == '2' || value == '3' || value == '4' || value == '5' || value == '6' || value == '7' || value == '8' || value == '9' || value == '10')) {callback(new Error('请输入正整数,值为[1,10]'));} else {callback();}}}, 100);
}16、验证是否是[1-100]的小数,即不可以等于0
export function isBtnOneToHundred(rule, value, callback) {if (!value) {return callback(new Error('输入不可以为空'));}setTimeout(() => {if (!Number(value)) {callback(new Error('请输入整数,值为[1,100]'));} else {if (value < 1 || value > 100) {callback(new Error('请输入整数,值为[1,100]'));} else {callback();}}}, 100);
}17、验证是否是[0-100]的小数
export function isBtnZeroToHundred(rule, value, callback) {if (!value) {return callback(new Error('输入不可以为空'));}setTimeout(() => {if (!Number(value)) {callback(new Error('请输入[1,100]之间的数字'));} else {if (value < 0 || value > 100) {callback(new Error('请输入[1,100]之间的数字'));} else {callback();}}}, 100);
}18、验证端口是否在[0,65535]之间
export function isPort(rule, value, callback) {if (!value) {return callback(new Error('输入不可以为空'));}setTimeout(() => {if (value == '' || typeof(value) == undefined) {callback(new Error('请输入端口值'));} else {const re = /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/;const rsCheck = re.test(value);if (!rsCheck) {callback(new Error('请输入在[0-65535]之间的端口值'));} else {callback();}}}, 100);
}19、验证端口是否在[0,65535]之间,非必填,isMust表示是否必填
export function isCheckPort(rule, value, callback) {if (!value) {callback();}setTimeout(() => {if (value == '' || typeof(value) == undefined) {//callback(new Error('请输入端口值'));} else {const re = /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/;const rsCheck = re.test(value);if (!rsCheck) {callback(new Error('请输入在[0-65535]之间的端口值'));} else {callback();}}}, 100);
}20、小写字母
export function validateLowerCase(val) {const reg = /^[a-z]+$/;return reg.test(val);
}21、两位小数验证
const validateValidity = (rule, value, callback) => {if (!/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/.test(value)) {callback(new Error('最多两位小数!!!'));} else {callback();}
};22、是否大写字母
export function validateUpperCase(val) {const reg = /^[A-Z]+$/;return reg.test(val);
}23、是否大小写字母
export function validatAlphabets(val) {const reg = /^[A-Za-z]+$/;return reg.test(val);
}24、密码校验
export const validatePsdReg = (rule, value, callback) => {if (!value) {return callback(new Error('请输入密码'))}if (!/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$)([^\u4e00-\u9fa5\s]){6,20}$/.test(value)) {callback(new Error('请输入6-20位英文字母、数字或者符号(除空格),且字母、数字和标点符号至少包含两种'))} else {callback()}
}25、中文校验
export const validateContacts = (rule, value, callback) => {if (!value) {return callback(new Error('请输入中文'))}if (!/^[\u0391-\uFFE5A-Za-z]+$/.test(value)) {callback(new Error('不可输入特殊字符'))} else {callback()}
}26、身份证校验
export const ID = (rule, value, callback) => {if (!value) {return callback(new Error('身份证不能为空'))}if (! /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value)) {callback(new Error('请输入正确的二代身份证号码'))} else {callback()}
}27、账号校验
export const validateCode = (rule, value, callback) => {if (!value) {return callback(new Error('请输入账号'))}if (!/^(?![0-9]*$)(?![a-zA-Z]*$)[a-zA-Z0-9]{6,20}$/.test(value)) {callback(new Error('账号必须为6-20位字母和数字组合'))} else {callback()}
}28、纯数字校验
export const validateNumber = (rule, value, callback) => {let numberReg = /^\d+$|^\d+[.]?\d+$/if (value !== '') {if (!numberReg.test(value)) {callback(new Error('请输入数字'))} else {callback()}} else {callback(new Error('请输入值'))}
}29、最多一位小数
const onePoint = (rule, value, callback) => {if (!/^[0-9]+([.]{1}[0-9]{1})?$/.test(value)) {callback(new Error('最多一位小数!!!'));} else {callback();}
};
module.exports = {Username(rule, value, callback) {let reg = /^(?![0-9]*$)(?![a-zA-Z]*$)[a-zA-Z0-9]{6,12}$/matching(value, callback, reg, '请输入6-12位字母和数字组合')}, SimplePwd(rule, value, callback) {let reg = /^[_a-zA-Z0-9]+$/matching(value, callback, reg, '包含英文字母、数字及下划线组成')}, ComplexPwd(rule, value, callback) {let reg = /^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$)([^\u4e00-\u9fa5\s]){8,20}$/matching(value, callback, reg, '请输入8-20位英文字母、数字或者符号')}, Phone(rule, value, callback) {let reg = /^[1][3, 4, 5, 6, 7, 8][0-9]{9}$/matching(value, callback, reg, '请输入正确的手机')}, Email(rule, value, callback) {let reg = /^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$/matching(value, callback, reg, '输入正确的邮箱')}, IdCard(rule, value, callback) { let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/ matching(value, callback, reg, '输入正确的身份证号码') }, Company(rule, value, callback) {let reg = /^[A-Z0-9]{8}-[A-Z0-9]$|^[A-Z0-9]{8}-[A-Z0-9]-[0-9]{2}$/matching(value, callback, reg, '请输入正确的营业执照')}, Weixin(rule, value, callback) {let reg = /^[a-zA-Z][a-zA-Z0-9_-]{5,19}$/matching(value, callback, reg, '请输入正确的微信号')}, Integer(rule, value, callback) {let reg = /^[1-9][0-9]*$/matching(value, callback, reg, '请输入正确的整数')}, Number(rule, value, callback) { let reg = /^\d+$|^\d+[.]?\d+$/  matching(value, callback, reg, '请输入纯数字') }, Landline(rule, value, callback) { let reg = /^(\d{3,4}-)?\d{7,8}$/   matching(value, callback, reg, '请输入正确的座机') },Ip(rule, value, callback) {let reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/  matching(value, callback, reg, '请输入正确的IP')},Price(rule, value, callback) { let reg = /^-?\d{1,4}(?:\.\d{1,2})?$ /  matching(value, callback, reg, '请输入正确的价格') }, BankCard(rule, value, callback) { let reg = /^([1-9]{1})(\d{14}|\d{18})$/   matching(value, callback, reg, '请输入正确的银行卡') }
}

相关文章:

正则表达式详解

这里写目录标题 一、基本概念1.基本语法2.修饰符3.方括号4.元字符5.量词 二、结构1.匹配模式2.字符组3.量词4.贪婪匹配和惰性匹配5.多选分支6.匹配模式关键词 三、位置1.位置锚点2.分组与引用1.分组与编号2.不保存子组3.括号嵌套4.命名捕获组5.引用捕获组 3.回溯匹配 四、对象方…...

动态扩缩容引发的JVM堆内存震荡:从原理到实践的GC调优指南

目录 一、典型案例&#xff1a;系统发布后的GC雪崩事件 &#xff08;一&#xff09;故障现象 1. 刚刚启动时 GC 次数较多 2. 堆内存锯齿状波动 3. GC日志特征&#xff1a;Allocation Failure &#xff08;二&#xff09;问题定位 二、原理深度解析&#xff1a;JVM内存弹…...

本地运行Manus的替代方案:OpenManus的技术解析与实践指南

无需邀请码&#xff0c;三小时构建的开源智能体革命 一、背景&#xff1a;从Manus到OpenManus的技术突围 近期&#xff0c;AI智能体领域因Manus的发布引发热议。这款号称“全球首个通用型AI智能体”的产品&#xff0c;通过整合浏览器操作&#xff08;Browser Use&#xff09;…...

红果短剧安卓+IOS双端源码,专业短剧开发公司

给大家拆解一下红果短剧/河马短剧&#xff0c;这种看光解锁视频&#xff0c;可以挣金币的短剧APP。给大家分享一个相似的短剧APP源码&#xff0c;这个系统已接入穿山甲广告、百度广告、快手广告、腾讯广告等&#xff0c;类似红果短剧的玩法&#xff0c;可以看剧赚钱&#xff0c…...

ubuntu22.04本地部署OpenWebUI

一、简介 Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 AI 平台&#xff0c;旨在完全离线运行。它支持各种 LLM 运行器&#xff0c;如 Ollama 和 OpenAI 兼容的 API&#xff0c;并内置了 RAG 推理引擎&#xff0c;使其成为强大的 AI 部署解决方案。 二、安装 方法 …...

不同开发语言之for循环的用法、区别总结

一、Objective-C &#xff08;1&#xff09;标准的c风格 for (int i 0; i < 5; i) {NSLog("i %d", i); } &#xff08;2&#xff09;for in循环。 NSArray *array ["apple", "banana", "orange"]; for (NSString *fruit in …...

国产编辑器EverEdit - 宏功能介绍

1 宏 1.1 应用场景 宏是一种重复执行简单工作的利器&#xff0c;可以让用户愉快的从繁琐的工作中解放出来&#xff0c;其本质是对键盘和菜单的操作序列的录制&#xff0c;并不会识别文件的内容&#xff0c;属于无差别无脑执行。 特别是对一些有规律的重复按键动作&#xff0c;…...

【Linux跬步积累】—— 网络基础

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;Linux跬步积累 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日一题 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0…...

【银河麒麟高级服务器操作系统实例】虚拟机桥接网络问题分析及处理

更多银河麒麟操作系统产品及技术讨论&#xff0c;欢迎加入银河麒麟操作系统官方论坛 https://forum.kylinos.cn 了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer…...

深入剖析Android Service:原理、生命周期与实战应用

一、引言&#xff1a;开启 Service 探索之旅 在 Android 开发的广袤天地中&#xff0c;Service 堪称一颗璀璨的明星&#xff0c;占据着举足轻重的地位。它宛如一位幕后英雄&#xff0c;默默地在后台辛勤劳作&#xff0c;执行着各种至关重要的任务&#xff0c;却无需与用户进行…...

MLT媒体程序框架03:滤镜——loudness

EBU R.128协议 引用链接 EBU的全称为European Broadcasting Union &#xff0c;既欧洲广播联盟&#xff0c;为欧洲与北非各广播业者&#xff08;包含广播电台与电视台&#xff09;的合作组织&#xff0c;成立于1950年2月12日,有五十多个正式加盟国,总部位于瑞士日内瓦,目前中国…...

FreeRTOS第15篇:FreeRTOS链表实现细节03_List_t与ListItem_t的奥秘

文/指尖动听知识库-星愿 文章为付费内容,商业行为,禁止私自转载及抄袭,违者必究!!! 文章专栏:深入FreeRTOS内核:从原理到实战的嵌入式开发指南 1 FreeRTOS列表的核心数据结构 FreeRTOS的列表实现由两个关键结构体组成:List_t(列表)和ListItem_t(列表项)。它们共同…...

Spring Boot静态资源访问顺序

在 Spring Boot 中&#xff0c;static 和 public 目录都用于存放静态资源&#xff08;如 HTML、CSS、JavaScript、图片等文件&#xff09;&#xff0c;但它们在使用上有一些细微的区别。以下是它们的详细对比&#xff1a; 1. 默认优先级 Spring Boot 会按照以下优先级加载静态…...

什么是 spring 的循环依赖?

什么是 spring 的循环依赖&#xff1f; 首先&#xff0c;认识一下什么是循环依赖&#xff0c;举个例子&#xff1a;A 对象被 Spring 管理&#xff0c;并且引入的 B 对象&#xff0c;同样的 B 对象也被 Spring 管理&#xff0c;并且也引入的 A 对象。这种相互被引用的情况&#…...

RSA的理解运用与Pycharm组装Cryptodome库

1、RSA的来源 RSA通常指基于RSA算法的密码系统&#xff0c;令我没想到的是&#xff0c;其名字的来源竟然不是某个含有特别意义的单词缩写而成&#xff08;比如PHP&#xff1a;Hypertext Preprocessor(超文本预处理器)&#xff09;&#xff0c;而是由1977年提出该算法的三个歪果…...

AI数据分析:deepseek生成SQL

在当今数据驱动的时代&#xff0c;数据分析已成为企业和个人决策的重要工具。随着人工智能技术的快速发展&#xff0c;AI 驱动的数据分析工具正在改变我们处理和分析数据的方式。本文将着重介绍如何使用 DeepSeek 进行自动补全SQL 查询语句。 我们都知道&#xff0c;SQL 查询语…...

git的坑

不小心把工作区的代码全删掉了 首先是名字出错&#xff0c;不知为何gitee任意把我的名字更改。 导致无法push验证 git push -u origin "master 显示&#xff1a;fatal: Authentication failed for https://gitee.com/zhang-great/stm32-smart-security-system.git/ 我…...

小程序事件系统 —— 32 事件系统 - 事件分类以及阻止事件冒泡

在微信小程序中&#xff0c;事件分为 冒泡事件 和 非冒泡事件 &#xff1a; 冒泡事件&#xff1a;当一个组件的事件被触发后&#xff0c;该事件会向父节点传递&#xff1b;&#xff08;如果父节点中也绑定了一个事件&#xff0c;父节点事件也会被触发&#xff0c;也就是说子组…...

‌PLC数据类型和‌C#数据类型的数据类型映射表

数据类型映射表 ‌PLC数据类型‌C#数据类型读取方式‌补充说明BitboolDBX布尔值BytebyteDBB单字节无符号整数WordushortDBW16位无符号整数DWorduintDBD32位无符号整数Intshort16位有符号整数DIntint32位有符号整数RealfloatDBR单精度浮点数LRealdoubleDBL双精度浮点数Stringstr…...

全球首创!微软发布医疗AI助手,终结手写病历时代

今天凌晨&#xff0c;微软发布了医疗界首个用于临床工作流程的AI助手Microsoft Dragon Copilot。 Dragon Copilot是基于语音文本的混合架构&#xff0c;能够将医生的语音或临床口述内容实时转换为文本。例如&#xff0c;医生可以通过语音输入患者的病历信息、医嘱或诊断结果&a…...

每日一题----------异常处理

总结&#xff1a; NullPointerException&#xff1a;尝试使用一个空引用进行操作时抛出。 ArrayIndexOutOfBoundsException&#xff1a;数组下标越界时抛出。 ClassCastException&#xff1a;类型转换失败时抛出。 ArithmeticException&#xff1a;数学运算错误时抛出&#…...

HTML 属性(详细易懂)

HTML&#xff08;超文本标记语言&#xff09;是用于创建网页和其他可在浏览器中查看的内容的基础标记语言。HTML 属性是 HTML 元素的额外信息&#xff0c;它们提供了元素的更多细节&#xff0c;如元素的标识符、样式、行为等。在本文中&#xff0c;将详细介绍 HTML 属性&#x…...

基于火山引擎的DeepSeek-V3 api实现简单的数据查询功能

前言 现在ai比较火&#xff0c;ai可以极大的提高大家的工作效率&#xff0c;所以有空的话要学习下ai的使用 火山引擎大模型 火山引擎大模型广场&#xff0c;聚集了市面上常见的基座大模型&#xff0c;每个模型都有50Wtokens的免费调用量&#xff0c;可以方便大家调用 账号登…...

AI入门1:关键概念

1. 基础概念 ​AI&#xff08;Artificial Intelligence&#xff0c;人工智能&#xff09;​ 模拟人类智能的机器系统&#xff0c;具备学习、推理、决策等能力。 ​Machine Learning&#xff08;机器学习&#xff0c;ML&#xff09;​ 让计算机通过数据自动学习规律&#xff0c…...

WPS工具栏添加Mathtype加载项

问题描述&#xff1a; 分别安装好WPS和MathType之后&#xff0c;WPS工具栏没直接显示MathType工具&#xff0c;或者是前期使用正常&#xff0c;由于WPS更新之后MathType工具消失&#xff0c;如下图 解决办法 将文件“MathType Commands 2016.dotm”和“MathPage.wll”从Matht…...

【MySQL-数据类型】数据类型分类+数值类型+文本、二进制类型+String类型

一、数据类型分类 二、数值类型 1.bit类型 测试环境ubuntu 基本语法&#xff1a; bit[(M)]&#xff1a;位字段类型&#xff0c;M表示每个值的位数&#xff0c;范围从1&#xff5e;64&#xff1b;如果M被忽略&#xff0c;默认为1举例&#xff1a; create table testBit(id i…...

cuda矩阵转置算子(共享内存)

cpu版本 即为按行遍历行列互换 // 主机上的矩阵转置函数&#xff0c;用于验证结果 void cpuTranspose(const float *input, float *output, int n) {for (int row 0; row < n; row){for (int col 0; col < n; col){output[col * n row] input[row * n col];}} }gp…...

GB28181视频监控流媒体平台LiveGBS如何自定义收流端口区间以便减少收流端口数或解决端口冲突问题

LiveGBS GB28181流媒体服务在接收视频的时候默认是使用30000-30249&#xff0c; webrtc流播放端口区间默认是UDP的30250-30500区间。有些网络环境不方便开放这么大的端口区间&#xff0c;下面介绍下如何修改配置这个区间。 从页面上修改这个区间&#xff0c;端口区间尽量设置大…...

在Go语言中,判断变量是否为“空”(零值或未初始化状态)的方法总结

在Go语言中,判断变量是否为“空”(零值或未初始化状态)的方法因数据类型而异。以下是各类型变量的判断方法总结: 1. 基本类型 整数(int) 判断是否等于零值 0。 var i int if i == 0 { // 空 } 字符串(string) 判断是否等于空字符串 ""。 var s string if s =…...

VUE3开发-9、axios前后端跨域问题解决方案

VUE前端解决跨域问题 前端页面需要改写 如果无效&#xff0c;记得重启服务器 后端c#解决跨域问题 前端js取值&#xff0c;后端c#跨域_c# js跨域-CSDN博客...

利用 requestrepo 工具验证 XML外部实体注入漏洞

1. 前言 在数字化浪潮席卷的当下&#xff0c;网络安全的重要性愈发凸显。应用程序在便捷生活与工作的同时&#xff0c;也可能暗藏安全风险。XXE&#xff08;XML外部实体&#xff09;漏洞作为其中的典型代表&#xff0c;攻击者一旦利用它&#xff0c;便能窃取敏感信息、掌控服务…...

嵌入式开发之串行数据处理

前题 前面几篇文章写了关于嵌入式软件开发时&#xff0c;关于串行数据处理的一些相关内容&#xff0c;有兴趣的可以看看《嵌入式开发&#xff1a;软件架构、驱动开发与串行数据处理》、《嵌入式软件开发之生产关系模型》和《嵌入式开发之Modbus-RTU协议解析》相关的内容。从业十…...

深入解析 JVM —— 从基础概念到实战调优的全链路学习指南

文章目录 一、为什么要学习 JVM&#xff1f;1. 面试必备与技能提升2. 性能优化与问题诊断3. 编写高质量代码 二、JVM 基础概念与体系结构1. JVM 简介2. JDK、JRE 与 JVM 三、JVM 内存模型1. 线程私有区2. 线程共享区 四、类加载机制与双亲委派1. 类加载过程2. 双亲委派模型3. 动…...

LTC6804、LTC6811、LTC6813的使用

FSEC自制BMS第一步&#xff1a;从零开发使用LTC6804采集电池电压 LTC6811特性 LTC6811 是 LTC6804 的引脚兼容型升级器件&#xff0c;LTC6804官方已经不推荐选用 可测量多达 12 节串联电池 1.2mV 最大总测量误差 可堆叠式架构能支持几百个电池 内置 isoSPI™ 接口 可在 290μ…...

Spring 构造器注入和setter注入的比较

一、比较说明 在 Spring 框架中&#xff0c;构造器注入&#xff08;Constructor Injection&#xff09;和 Setter 注入&#xff08;Setter Injection&#xff09;是实现依赖注入&#xff08;DI&#xff09;的两种主要方式。它们的核心区别在于依赖注入的时机、代码设计理念以及…...

【LangChain】对话历史管理

1 历史记录的剪裁 trimmed_messages from langchain_core.messages import (AIMessage,HumanMessage,SystemMessage,trim_messages, ) from langchain_openai import ChatOpenAImessages [SystemMessage("youre a good assistant, you always respond with a joke."…...

【无人机三维路径规划】基于CPO冠豪猪优化算法的无人机三维路径规划Maltab

代码获取基于CPO冠豪猪优化算法的无人机三维路径规划Maltab 基于CPO冠豪猪优化算法的无人机三维路径规划 一、CPO算法的基本原理与核心优势 冠豪猪优化算法&#xff08;Crested Porcupine Optimizer, CPO&#xff09;是一种新型元启发式算法&#xff0c;其灵感来源于冠豪猪的…...

CAN协议介绍

目录 一、CAN协议 1.1 CAN协议简介 1.2 CAN物理层 1.3 CAN协议层 二、CAN控制器 2.1 CAN控制内核 2.2 CAN发送邮箱 2.3 CAN接收FIFO 2.4 CAN验收筛选器 一、CAN协议 1.1 CAN协议简介 CAN 是控制器局域网络 (Controller Area Network) 的简称&#xff0c;它是由研发和生…...

树莓派 Interface Option 中没有camera选项

最近重温树莓派的视觉&#xff0c;烧录了树莓派的新系统后发现在 raspi-config 中的 Interface Option 没有 camera 选项&#xff0c;同时在终端用 vcgencmd get_camera 查看摄像头时没有检测到树莓派的 CSI 摄像头&#xff0c;在 Thonny 中调用树莓派摄像头出现报错&#xff1…...

大数据学习(55)-BI工具数据分析的使用

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…...

轻松上手 —— 通过 RPM 包快速部署 NebulaGraph

前言 在当今大数据时代&#xff0c;处理复杂关系数据的需求与日俱增&#xff0c;图数据库应运而生并逐渐崭露头角。NebulaGraph 作为一款高性能、分布式且易扩展的图数据库&#xff0c;专为应对大规模图数据处理而精心打造。它不仅具备丰富的查询语言&#xff0c;还拥有强大高效…...

nginx作为下载服务器配置

一、Nginx 作为下载服务器配置笔记 基本配置指令 server块配置&#xff1a; 在 Nginx 的配置文件&#xff08;通常是/etc/nginx/nginx.conf或在/etc/nginx/conf.d/目录下的特定配置文件&#xff09;中&#xff0c;首先需要定义一个server块来监听特定的端口并处理下载请求。例如…...

第六课:数据存储三剑客:CSV/JSON/MySQL

在Python的数据存储与处理领域&#xff0c;CSV、JSON和MySQL被广大开发者誉为“数据存储三剑客”。它们各自在不同的场景下发挥着重要作用&#xff0c;无论是简单的数据交换、轻量级的数据存储&#xff0c;还是复杂的关系型数据库管理&#xff0c;都能找到它们的身影。本文将详…...

Dify 开源大语言模型应用开发平台使用(一)

文章目录 一、创建锂电池专业知识解答应用1.1 应用初始化二、核心功能模块详解2.1 知识库构建2.2 工作流与节点编排节点类型说明工作流设计示例:锂电池选型咨询2.3 变量管理三、测试与调试3.1 单元测试3.2 压力测试3.3 安全验证四、部署与优化建议4.1 部署配置4.2 持续优化结论…...

PyQt高亮代码

PyQt高亮代码 安装 Pygments支持的格式支持的样式详解参考 Qt中使用 安装 Pygments Pygments 是Python中的一个高亮代码的包&#xff0c;挺好用的 pip install Pygments支持的格式 支持的格式比较多&#xff0c;不列出来了 # coding:utf-8 from pygments.lexers import get_all…...

小白学Agent技术[1]

文章目录 课程地址Agent介绍原理架构任务规划记忆工具使用程序开发范式的变化Agent开发注意事项 课程地址 Agent课程地址 Agent介绍 AI Agent&#xff08;人工智能代理、AI智能体&#xff09;&#xff0c;一种模拟人类智能行为的人工智能系统&#xff0c;以大模型语言&#…...

以商业思维框架为帆,驭创业浪潮前行

创业者踏入商海&#xff0c;如同航海家奔赴未知海域&#xff0c;需有清晰的思维罗盘指引方向。图中“为什么—用什么—怎么做—何人做—投入产出”的商业框架&#xff0c;正是创业者破解商业谜题的密钥&#xff0c;从需求洞察到落地执行&#xff0c;为创业之路铺就逻辑基石。 …...

开源宝藏 Tigshop,开启电商新征程

在电商竞争愈发激烈的当下&#xff0c;一个强大且适配的商城系统是商家制胜的法宝。 Tigshop官网&#xff1a;Tigshop官网 - 开源商城系统Tigshop开源商城系统&#xff0c;支持b2b2c、多商户、多店铺、商家入驻、分销系统、跨境电商、连锁商城等解决方案&#xff0c;免费下载&…...

java多线程实现方式

目录 1. 继承 Thread 类 2. 实现 Runnable 接口 3. 实现 Callable 接口 4. 使用线程池 5. 使用 CompletableFuture&#xff08;Java 8&#xff09; 6. 使用 ForkJoinPool&#xff08;Java 7&#xff09; 7. 使用 Timer 和 TimerTask 8. 使用 ScheduledExecutorService …...

windows:curl: (60) schannel: SEC_E_UNTRUSTED_ROOT (0x80090325)

目录 1. git update-git-for-windows 报错2. 解决方案2.1. 更新 CA 证书库2.2. 使用 SSH 连接&#xff08;推荐&#xff09;2.3 禁用 SSL 验证&#xff08;不推荐&#xff09; 1. git update-git-for-windows 报错 LenovoLAPTOP-EQKBL89E MINGW64 /d/YHProjects/omni-channel-…...