JS正则表达式介绍(JavaScript正则表达式)
文章目录
- JavaScript正则表达式完全指南
- 正则表达式基础
- 元字符与特殊字符
- 基本元字符
- `.` - 点号
- `\d` - 数字
- `\D` - 非数字
- `\w` - 单词字符
- `\W` - 非单词字符
- `\s` - 空白字符
- `\S` - 非空白字符
- 正则表达式标志
- 常用标志详解
- `g` - 全局匹配
- `i` - 忽略大小写
- `m` - 多行匹配
- `s` - 点号匹配所有字符
- `u` - Unicode模式
- `y` - 粘性匹配
- 组合使用标志
- 在RegExp构造函数中使用标志
- 通过属性检查标志
- 量词与边界
- 量词
- `*` - 零次或多次
- `+` - 一次或多次
- `?` - 零次或一次
- `{n}` - 恰好n次
- `{n,}` - 至少n次
- `{n,m}` - n到m次
- 边界匹配
- `^` - 行首
- `$` - 行尾
- `\b` - 单词边界
- `\B` - 非单词边界
- 分组与捕获
- 基本分组
- 命名捕获组
- 断言与零宽断言
- `(?=...)` - 正向前瞻
- `(?!...)` - 负向前瞻
- `(?<=...)` - 正向后顾
- `(?<!...)` - 负向后顾
- JavaScript中的正则表达式方法
- String对象的方法
- `search()` - 查找匹配
- `replace()` - 替换匹配
- `split()` - 分割字符串
- `match()` - 获取匹配
- `matchAll()` - 获取所有匹配信息
- RegExp对象的方法
- `test()` - 测试匹配
- `exec()` - 执行匹配
- 高级应用与技巧
- 贪婪与非贪婪匹配
- 贪婪匹配
- 非贪婪匹配
- 常见应用场景
- 验证电子邮箱
- 验证手机号
- 提取URL参数
- 性能优化
- 避免回溯过多
- 使用非捕获组
- 总结
JavaScript正则表达式完全指南
正则表达式基础
正则表达式是一种强大的文本处理工具,用于匹配、搜索和替换文本中的特定模式。在JavaScript中,正则表达式是一种对象,可以通过字面量或构造函数创建。
// 使用字面量创建正则表达式
const pattern1 = /hello/;
// 这里创建了一个匹配"hello"字符串的正则表达式// 使用构造函数创建正则表达式
const pattern2 = new RegExp("hello");
// 这种方法也创建了一个匹配"hello"的正则表达式,效果与上面相同
元字符与特殊字符
正则表达式的强大之处在于其元字符系统,这些特殊字符具有特殊含义。
基本元字符
.
- 点号
匹配除换行符外的任意单个字符
// 使用点号匹配任意字符
const dotPattern = /h.t/g;
"hit hot hat h t".match(dotPattern); // 结果: ["hit", "hot", "hat"]
// 解释: 点号匹配除换行符外的任意字符,所以匹配到"hit", "hot", "hat",但不匹配"h t"
\d
- 数字
匹配任何数字字符(0-9)
// 匹配任意数字
const digitPattern = /\d/g;
"abc123".match(digitPattern); // 结果: ["1", "2", "3"]
// 解释: \d匹配任意单个数字,g标志表示全局匹配,所以找到了所有数字
\D
- 非数字
匹配任何非数字字符
// 匹配任意非数字字符
const nonDigitPattern = /\D/g;
"abc123".match(nonDigitPattern); // 结果: ["a", "b", "c"]
// 解释: \D匹配任意非数字字符,所以匹配到了字母a、b和c
\w
- 单词字符
匹配字母、数字、下划线
// 匹配单词字符
const wordCharPattern = /\w/g;
"a1_!".match(wordCharPattern); // 结果: ["a", "1", "_"]
// 解释: \w匹配字母、数字和下划线,所以匹配到a、1和_,但不匹配!
\W
- 非单词字符
匹配非字母、数字、下划线的字符
// 匹配非单词字符
const nonWordCharPattern = /\W/g;
"a1_!".match(nonWordCharPattern); // 结果: ["!"]
// 解释: \W匹配非字母、数字、下划线的字符,所以只匹配到!
\s
- 空白字符
匹配空格、制表符、换行符等空白字符
// 匹配空白字符
const whitespacePattern = /\s/g;
"a b\tc\nd".match(whitespacePattern); // 结果: [" ", "\t", "\n"]
// 解释: \s匹配任意空白字符,所以匹配到空格、制表符和换行符
\S
- 非空白字符
匹配任何非空白字符
// 匹配所有非空白字符
const nonWhitespacePattern = /\S/g;
"hello world".match(nonWhitespacePattern); // 结果: ["h","e","l","l","o","w","o","r","l","d"]
// 解释: \S匹配任意非空白字符,这里匹配了所有字母,空格被排除
正则表达式标志
正则表达式末尾的字母是"标志"(flags),用于控制正则表达式的匹配行为。这些标志放在正则表达式的结束斜杠/
之后。
// 格式: /pattern/flags
const regex = /hello/g; // g是全局匹配标志
// 这个正则表达式会匹配所有出现的"hello",而不仅仅是第一个
常用标志详解
g
- 全局匹配
启用全局搜索,查找所有匹配项而不是只找第一个
// 不带g标志 - 只匹配第一个结果
"hello hello".match(/hello/); // 结果: ["hello"]
// 解释: 没有g标志,所以只返回第一个匹配的"hello"// 带g标志 - 匹配所有结果
"hello hello".match(/hello/g); // 结果: ["hello", "hello"]
// 解释: 有g标志,所以返回所有匹配的"hello",这里有两个
i
- 忽略大小写
进行不区分大小写的匹配
// 不带i标志 - 区分大小写
"Hello".match(/hello/); // 结果: null
// 解释: 默认区分大小写,所以"Hello"与"hello"不匹配,返回null// 带i标志 - 忽略大小写
"Hello".match(/hello/i); // 结果: ["Hello"]
// 解释: i标志使匹配不区分大小写,所以"Hello"与"hello"匹配成功
m
- 多行匹配
允许^和$匹配每一行的开始和结束
const multiline = "line1\nline2\nline3";// 不带m标志 - ^和$只匹配整个字符串的开始和结束
multiline.match(/^line/g); // 结果: ["line"]
// 解释: 没有m标志,^只匹配整个字符串的开始,所以只匹配到第一行的"line"// 带m标志 - ^和$匹配每一行的开始和结束
multiline.match(/^line/gm); // 结果: ["line", "line", "line"]
// 解释: 有m标志,^匹配每一行的开始,所以匹配到所有三行开头的"line"
s
- 点号匹配所有字符
让点号(.)匹配包括换行符在内的所有字符
const text = "line1\nline2";// 不带s标志 - 点号不匹配换行符
text.match(/line1.line2/); // 结果: null
// 解释: 没有s标志,.不匹配换行符\n,所以模式不匹配// 带s标志 - 点号匹配包括换行符在内的所有字符
text.match(/line1.line2/s); // 结果: ["line1\nline2"]
// 解释: 有s标志,.可以匹配换行符\n,所以整个模式匹配成功
u
- Unicode模式
启用完整的Unicode支持
// 启用Unicode属性转义
/\p{Script=Greek}/u.test('π'); // 结果: true
// 解释: u标志启用Unicode支持,允许使用\p{...}匹配特定Unicode属性,这里匹配希腊文字符// 正确处理Unicode代理对
"𠮷".match(/./u)[0].length; // 结果: 1 (正确识别为单个字符)
// 解释: u标志使得正则表达式正确处理占用两个代码单元的Unicode字符,如"𠮷",识别为一个字符
y
- 粘性匹配
仅从正则表达式的lastIndex属性开始匹配
const str = "first second";
const sticky = /\w+/y;
sticky.lastIndex = 6; // 设置开始搜索位置为6(即"second"的开始位置)
sticky.test(str); // 结果: true,匹配"second"
// 解释: y标志使正则表达式只从指定的lastIndex位置开始匹配,匹配到了"second"// 如果设置位置不是单词开头,则不匹配
sticky.lastIndex = 7; // 设置到"econd"
sticky.test(str); // 结果: false
// 解释: lastIndex设为7,不是单词开头,y标志要求必须从lastIndex位置精确匹配,所以匹配失败
组合使用标志
标志可以组合使用,实现更灵活的匹配行为:
// 全局匹配 + 忽略大小写
"Hello hello HELLO".match(/hello/gi); // 结果: ["Hello", "hello", "HELLO"]
// 解释: g标志使匹配全局化,i标志使匹配不区分大小写,所以找到所有大小写形式的"hello"// 全局匹配 + 多行匹配
const text = "Line1\nLine2\nLine3";
text.match(/^Line\d$/gm); // 结果: ["Line1", "Line2", "Line3"]
// 解释: g标志使匹配全局化,m标志使^和$分别匹配每行的开始和结束,
// \d匹配一个数字,所以匹配到每行的完整内容
在RegExp构造函数中使用标志
// 使用字符串第二参数指定标志
const regex1 = new RegExp("pattern", "gi");
// 解释: 创建一个正则表达式匹配"pattern",带有g(全局)和i(忽略大小写)标志// 从现有正则复制并添加新标志
const originalRegex = /pattern/g;
const newRegex = new RegExp(originalRegex, "i"); // 结果: /pattern/gi
// 解释: 从已有的带g标志的正则表达式创建新的正则表达式,并添加i标志
通过属性检查标志
const regex = /test/gi;regex.global; // true (是否有g标志)
regex.ignoreCase; // true (是否有i标志)
regex.multiline; // false (是否有m标志)
regex.dotAll; // false (是否有s标志)
regex.unicode; // false (是否有u标志)
regex.sticky; // false (是否有y标志)
// 解释: 通过正则表达式对象的属性可以检查该正则表达式是否设置了特定标志
量词与边界
量词
*
- 零次或多次
匹配前一项0次或多次
// 使用*匹配0次或多次
const starPattern = /ab*c/g;
"ac abc abbc".match(starPattern); // 结果: ["ac", "abc", "abbc"]
// 解释: b*匹配0个或多个b,所以匹配到"ac"(0个b)、"abc"(1个b)和"abbc"(2个b)
+
- 一次或多次
匹配前一项1次或多次
// 使用+匹配1次或多次
const plusPattern = /ab+c/g;
"ac abc abbc".match(plusPattern); // 结果: ["abc", "abbc"]
// 解释: b+匹配1个或多个b,所以匹配到"abc"和"abbc",但不匹配"ac"(没有b)
?
- 零次或一次
匹配前一项0次或1次
// 使用?匹配0次或1次
const questionPattern = /ab?c/g;
"ac abc abbc".match(questionPattern); // 结果: ["ac", "abc"]
// 解释: b?匹配0个或1个b,所以匹配到"ac"和"abc",但不匹配"abbc"(有2个b)
{n}
- 恰好n次
匹配前一项恰好n次
// 使用{n}匹配恰好n次
const exactPattern = /ab{2}c/g;
"abc abbc abbbc".match(exactPattern); // 结果: ["abbc"]
// 解释: b{2}匹配恰好2个b,所以只匹配到"abbc"
{n,}
- 至少n次
匹配前一项至少n次
// 使用{n,}匹配至少n次
const atLeastPattern = /ab{2,}c/g;
"abc abbc abbbc".match(atLeastPattern); // 结果: ["abbc", "abbbc"]
// 解释: b{2,}匹配至少2个b,所以匹配到"abbc"(2个b)和"abbbc"(3个b)
{n,m}
- n到m次
匹配前一项至少n次,最多m次
// 使用{n,m}匹配n到m次
const rangePattern = /ab{1,2}c/g;
"abc abbc abbbc".match(rangePattern); // 结果: ["abc", "abbc"]
// 解释: b{1,2}匹配1到2个b,所以匹配到"abc"(1个b)和"abbc"(2个b),但不匹配"abbbc"(3个b)
边界匹配
^
- 行首
匹配输入的开始位置,在多行模式下匹配每一行的开始
// 使用^匹配行首
const startPattern = /^start/;
"start line\nanother line".match(startPattern); // 结果: ["start"]
// 解释: ^匹配字符串开头,所以匹配到开头的"start"// 在多行模式下
const multilineStartPattern = /^line/gm;
"first line\nline two".match(multilineStartPattern); // 结果: ["line"]
// 解释: 在多行模式下,^匹配每行的开头,所以匹配到第二行开头的"line"
$
- 行尾
匹配输入的结束位置,在多行模式下匹配每一行的结束
// 使用$匹配行尾
const endPattern = /end$/;
"line end\nline".match(endPattern); // 结果: ["end"]
// 解释: $匹配字符串结尾,所以匹配到第一行结尾的"end"// 在多行模式下
const multilineEndPattern = /line$/gm;
"first line\nline two".match(multilineEndPattern); // 结果: ["line"]
// 解释: 在多行模式下,$匹配每行的结尾,所以匹配到第一行结尾的"line"
\b
- 单词边界
匹配单词边界,即字母与非字母之间的位置
// 匹配以字母a开头的单词
const startsWithA = /\ba\w*/g;
"apple banana grape avocado".match(startsWithA); // 结果: ["apple", "avocado"]
// 解释: \b匹配单词边界,a匹配字母a,\w*匹配零个或多个字母、数字或下划线,
// 所以匹配以a开头的单词"apple"和"avocado"
\B
- 非单词边界
匹配非单词边界
// 匹配不在单词边界的'a'
const nonBoundaryA = /\Ba\w*/g;
"apple banana grape avocado".match(nonBoundaryA); // 结果: ["ana"]
// 解释: \B匹配非单词边界,a匹配字母a,\w*匹配零个或多个字母、数字或下划线,
// 所以匹配到"banana"中的"ana",因为这个'a'不在单词开头
分组与捕获
基本分组
使用圆括号()
可以将正则表达式的一部分组合起来,作为一个单元。
// 匹配重复的单词
const repeatedWord = /(\w+)\s+\1/g;
"hello hello world".match(repeatedWord); // 结果: ["hello hello"]
// 解释:
// (\w+) - 捕获组,匹配一个或多个单词字符(字母、数字或下划线)
// \s+ - 匹配一个或多个空白字符
// \1 - 反向引用,引用第一个捕获组匹配的内容
// 整体匹配连续重复的单词,如"hello hello"// 捕获组的使用
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2023-05-15".match(datePattern);
// match[0]: "2023-05-15" (完整匹配)
// match[1]: "2023" (第一个捕获组 - 年份)
// match[2]: "05" (第二个捕获组 - 月份)
// match[3]: "15" (第三个捕获组 - 日期)
// 解释: 每个括号内的内容形成一个捕获组,匹配结果中可以通过索引访问每个捕获组
命名捕获组
ES2018引入了命名捕获组,使得访问捕获的内容更加直观。
// 使用命名捕获组解析日期
const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = "2023-05-15".match(datePattern);
// match.groups.year: "2023"
// match.groups.month: "05"
// match.groups.day: "15"
// 解释:
// (?<year>\d{4}) - 命名为"year"的捕获组,匹配四位数字
// (?<month>\d{2}) - 命名为"month"的捕获组,匹配两位数字
// (?<day>\d{2}) - 命名为"day"的捕获组,匹配两位数字
// 通过match.groups对象可以按名称访问捕获的内容,更加直观
断言与零宽断言
断言不消耗字符,只进行位置匹配。
(?=...)
- 正向前瞻
匹配后面跟着特定模式的位置
// 前瞻断言:匹配后面跟着"张"的所有字符
const lookAheadPattern = /\w+(?=张)/g;
"李明张三王五".match(lookAheadPattern); // 结果: ["李明"]
// 解释: \w+匹配一个或多个字符,(?=张)是一个前瞻断言,表示后面必须跟着"张"
// 所以匹配到"李明",因为它后面是"张"
(?!...)
- 负向前瞻
匹配后面不跟着特定模式的位置
// 负前瞻:匹配后面不是数字的字母序列
const negativeLookAhead = /[a-z]+(?!\d)/g;
"abc1 def2 ghi".match(negativeLookAhead); // 结果: ["ab", "de", "ghi"]
// 解释: [a-z]+匹配一个或多个小写字母,(?!\d)是一个负前瞻断言,表示后面不能是数字
// 所以匹配到"abc1"中的"ab"(c后面是数字1),"def2"中的"de"(f后面是数字2),
// 以及"ghi"(后面没有任何字符)
(?<=...)
- 正向后顾
匹配前面有特定模式的位置
// 后顾断言:匹配前面是数字的字母
const lookBehindPattern = /(?<=\d)[a-z]+/g;
"1apple 2banana 3grape".match(lookBehindPattern); // 结果: ["apple", "banana", "grape"]
// 解释: (?<=\d)是一个后顾断言,表示前面必须有一个数字
// [a-z]+匹配一个或多个小写字母
// 所以匹配到跟在数字后面的字母序列:"apple"、"banana"和"grape"
(?<!...)
- 负向后顾
匹配前面没有特定模式的位置
// 负后顾断言:匹配前面不是数字的字母
const negativeLookBehindPattern = /(?<!\d)[a-z]+/g;
"1apple word 2banana".match(negativeLookBehindPattern); // 结果: ["word"]
// 解释: (?<!\d)是一个负后顾断言,表示前面不能是数字
// [a-z]+匹配一个或多个小写字母
// 所以只匹配到"word",因为它前面不是数字
JavaScript中的正则表达式方法
String对象的方法
search()
- 查找匹配
查找字符串中是否存在匹配,返回首次匹配的位置索引,如果没有匹配则返回-1
const str = "JavaScript正则表达式很强大";
const pattern = /正则表达式/;// 测试是否包含模式
str.search(pattern); // 返回首次匹配的索引: 10
// 解释: search方法返回第一个匹配的位置索引,这里"正则表达式"从索引10开始
replace()
- 替换匹配
将匹配的文本替换为指定内容
const str = "JavaScript正则表达式很强大";
const pattern = /正则表达式/;// 替换匹配内容
str.replace(pattern, "RegExp"); // 结果: "JavaScriptRegExp很强大"
// 解释: replace方法将匹配的"正则表达式"替换为"RegExp"
split()
- 分割字符串
使用正则表达式匹配的内容作为分隔符来分割字符串
// 分割字符串
"apple,banana,orange".split(/,/); // 结果: ["apple", "banana", "orange"]
// 解释: split方法根据正则表达式匹配的内容(这里是逗号)分割字符串
match()
- 获取匹配
获取字符串中匹配正则表达式的部分
const str = "JavaScript正则表达式很强大";// 匹配所有结果
const matches = str.match(/\w+/g); // 结果: ["JavaScript"]
// 解释: match方法返回匹配的结果,\w+匹配一个或多个字母、数字或下划线字符
// 这里只匹配到拉丁字符部分"JavaScript",因为\w默认不匹配中文字符
matchAll()
- 获取所有匹配信息
返回一个包含所有匹配结果的迭代器
const str = "test1 test2 test3";
const regexp = /test(\d)/g;
const matches = [...str.matchAll(regexp)];// matches[0]: ["test1", "1"] (第一次匹配及其捕获组)
// matches[1]: ["test2", "2"] (第二次匹配及其捕获组)
// matches[2]: ["test3", "3"] (第三次匹配及其捕获组)
// 解释: matchAll返回所有匹配的信息,包括每次匹配的完整字符串和捕获组
RegExp对象的方法
test()
- 测试匹配
测试字符串是否匹配正则表达式模式,返回布尔值
const pattern = /Java(Script)/;
const str = "JavaScript是一种脚本语言";// 测试是否匹配
pattern.test(str); // 结果: true
// 解释: test方法检查字符串是否匹配正则表达式,返回布尔值
exec()
- 执行匹配
在字符串中执行匹配搜索,返回详细的匹配信息
const pattern = /Java(Script)/;
const str = "JavaScript是一种脚本语言";// 获取匹配信息
const execResult = pattern.exec(str);
// execResult[0]: "JavaScript" (完整匹配)
// execResult[1]: "Script" (第一个捕获组)
// execResult.index: 0 (匹配位置)
// 解释: exec方法返回一个数组,包含匹配的完整字符串和所有捕获组,
// 以及匹配的位置信息(index属性)
高级应用与技巧
贪婪与非贪婪匹配
贪婪匹配
默认情况下,正则表达式的量词是贪婪的,会尽可能多地匹配字符
const text = "<div>内容1</div><div>内容2</div>";// 贪婪匹配 - 匹配尽可能长的字符串
const greedyPattern = /<div>.*<\/div>/;
text.match(greedyPattern)[0]; // 结果: "<div>内容1</div><div>内容2</div>"
// 解释: .*是贪婪匹配,会匹配尽可能多的字符,所以匹配了整个字符串从第一个<div>到最后一个</div>
非贪婪匹配
在量词后添加?
使其变为非贪婪匹配,会尽可能少地匹配字符
const text = "<div>内容1</div><div>内容2</div>";// 非贪婪匹配 - 匹配尽可能短的字符串
const nonGreedyPattern = /<div>.*?<\/div>/g;
text.match(nonGreedyPattern); // 结果: ["<div>内容1</div>", "<div>内容2</div>"]
// 解释: .*?是非贪婪匹配,会匹配尽可能少的字符,加上g标志匹配所有可能的结果,
// 所以分别匹配到了两个完整的div标签内容
常见应用场景
验证电子邮箱
使用正则表达式验证电子邮件地址格式
// 验证电子邮箱
const emailPattern = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
emailPattern.test("test@example.com"); // 结果: true
// 解释:
// ^[\w-]+ - 以一个或多个字母、数字、下划线或连字符开始
// (\.[\w-]+)* - 可能跟着点号和更多字符(如user.name)
// @ - 然后是@符号
// ([\w-]+\.)+ - 一个或多个由点号分隔的域名部分
// [a-zA-Z]{2,7}$ - 以2-7个字母的顶级域名结束
验证手机号
验证中国大陆手机号格式
// 验证中国手机号
const phonePattern = /^1[3-9]\d{9}$/;
phonePattern.test("13812345678"); // 结果: true
// 解释:
// ^1 - 以数字1开头
// [3-9] - 第二位是3到9之间的数字
// \d{9}$ - 后面跟着9个数字结束
// 此正则匹配中国大陆常见的11位手机号码
提取URL参数
从URL中提取查询参数
// 提取URL参数
function getUrlParams(url) {const pattern = /[?&]([^=&#]+)=([^&#]*)/g;const params = {};let match;while ((match = pattern.exec(url)) !== null) {// match[1]: 参数名// match[2]: 参数值params[match[1]] = decodeURIComponent(match[2]);}return params;
}// 示例
const url = "https://example.com/search?query=正则表达式&lang=zh&page=1";
const params = getUrlParams(url);
// 结果: {query: "正则表达式", lang: "zh", page: "1"}
// 解释:
// [?&] - 匹配问号或&符号(URL参数的开始)
// ([^=&#]+) - 第一个捕获组匹配参数名(不包含=、&、#的字符序列)
// = - 匹配等号
// ([^&#]*) - 第二个捕获组匹配参数值(不包含&、#的字符序列)
// 循环使用exec方法获取所有参数,并构建参数对象
性能优化
避免回溯过多
避免使用可能导致灾难性回溯的模式
// 避免回溯过多
// 不良示例 - 可能导致灾难性回溯
const badPattern = /^(\w+)+$/;
// 解释: 这种嵌套量词的模式((\w+)+)可能导致指数级回溯,
// 对于某些输入可能引起正则表达式引擎长时间计算甚至崩溃// 改进版本
const betterPattern = /^\w+$/;
// 解释: 简化版本,仅匹配一个或多个单词字符,没有嵌套量词,性能更好
使用非捕获组
当不需要引用捕获内容时,使用非捕获组提高性能
// 避免使用不必要的捕获组
// 不良示例
const capturePattern = /(\d+)-(\d+)-(\d+)/;
// 解释: 如果不需要使用捕获的内容,这些捕获组会消耗额外的内存和处理时间// 非捕获组版本 - 如果不需要使用捕获的内容
const nonCapturePattern = /(?:\d+)-(?:\d+)-(?:\d+)/;
// 解释: 使用非捕获组(?:...)代替捕获组(),如果不需要引用匹配的内容,
// 这样可以提高性能,特别是在大型文本处理中
总结
JavaScript正则表达式是一种强大的文本处理工具,掌握其基本语法和高级技巧可以大幅提高文本处理效率。正则表达式由元字符、量词、分组等组成,通过合理组合这些元素,能够实现复杂的模式匹配需求。正确理解和使用标志(flags)可以让正则表达式匹配更精确、更高效,适应不同的文本处理需求。在实际应用中,需要注意正则表达式的可读性和性能问题,避免过于复杂的模式导致难以维护或性能下降。
相关文章:
JS正则表达式介绍(JavaScript正则表达式)
文章目录 JavaScript正则表达式完全指南正则表达式基础元字符与特殊字符基本元字符. - 点号\d - 数字\D - 非数字\w - 单词字符\W - 非单词字符\s - 空白字符\S - 非空白字符 正则表达式标志常用标志详解g - 全局匹配i - 忽略大小写m - 多行匹配s - 点号匹配所有字符u - Unicod…...

AI安全之对抗样本攻击---FGSM实战脚本解析
一、对抗样本与FGSM的背景 在深度学习安全领域,对抗样本(Adversarial Examples)因其特殊的生成机制备受关注。2015年ICLR会议收录的里程碑式论文《Explaining and Harnessing Adversarial Examples》中,Goodfellow等学者首次系统…...

《Python星球日记》 第50天:深度学习概述与环境搭建
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、什么是深度学习?它与传统机器学习的区别1. 深度学习的定义2. 深…...
Android开发-图像显示
在Android应用开发中,图像显示是提升用户体验的重要元素之一。无论是展示产品图片、用户头像还是应用程序图标,合理地使用图像资源可以显著增强界面的吸引力和功能性。本文将详细介绍如何在Android应用中有效地显示图像,包括加载本地与网络图…...

linux搭建hadoop学习
linux搭建hadoop学习 下载安装包: 海外资源可能需要翻墙或者找国内资源 cd /opt wget https://dlcdn.apache.org/hadoop/common/hadoop-2.10.2/hadoop-2.10.2.tar.gz tar -zxvf hadoop-2.10.2.tar.gz mv hadoop-2.10.2 hadoop配置环境变量 # 在/etc/profile文件中添加下面内…...

PyTorch API 8 - 工具集、onnx、option、复数、DDP、量化、分布式 RPC、NeMo
文章目录 torch.nn.inittorch.nn.attention工具集子模块 torch.onnx概述基于 TorchDynamo 的 ONNX 导出器基于TorchScript的ONNX导出器贡献与开发 torch.optim如何使用优化器构建优化器每个参数的选项执行优化步骤optimizer.step()optimizer.step(closure) 基类算法如何调整学习…...

0基础 | STM32 | TB6612电机驱动使用
TB6612介绍及使用 单片机通过驱动板连接至电机 原因:单品机I/O口输出电流I小 驱动板:从外部引入高电压,控制电机驱动 电源部分 VM:电机驱动电源输入,输入电压范围建议为3.7~12V GND:逻辑电…...

【Linux】POSIX 线程信号量与互斥锁▲
代码要求:高内聚,低耦合 高内聚:元素之间具有很强的关联性,模块的功能单一且集中 低耦合:代码之间的依赖关系尽可能简单,相互之间的影响和交互尽可能少 线程安全问题:多线程访问共享数据&…...
轻松制作高质量视频,实时生成神器LTX-Video重磅登场!
探索LTX-Video:实时视频生成跨越新高度 在如今这个视觉内容主导的数字时代,视频生成成为推动创意表达的关键。而今天,我们将带您深入探索LTX-Video,一个强大的开源项目,致力于通过尖端技术将视频生成提升到一个全新的…...

USR-M100采集数据并提交MQTT服务器
本文为记录备忘,不做过多解释。 模块自身带有2路数字量输入,2路模拟量输入,2路485接口 数字量接报警输入,模拟量接压力传感器,液位传感器,485接口分别接流量计,温湿度传感器。 正确接线&…...

内网穿透系列三:开源本地服务公网映射工具 tunnelmole
以下是对 tunnelmole 简要介绍: tunnelmole 是一款开源的内网穿透工具,一行命令就能把本地http服务映射成公网可访问的链接提供公共免费的网络服务,直接下载运行命令即可使用,也支持自行配置搭建私有客户端、服务端参考开源地址&…...

数据集-目标检测系列- 冥想 检测数据集 close_eye>> DataBall
数据集-目标检测系列- 冥想 检测数据集 close * 相关项目 1)数据集可视化项目:gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview 2)数据集训练、推理相关项目:GitHub - XIAN-HHappy/ultralytics-yolo-…...
计算机网络:家庭路由器WiFi信号的发射和手机终端接收信号原理?
WiFi路由器与手机之间的信号传输涉及多个技术层面的协作,以下是其工作原理的详细步骤: 一、数据封装与协议处理 应用层数据生成 用户操作(如浏览网页、视频播放)产生数据包,经TCP/IP协议栈逐层封装,添加IP地址(网络层)和MAC地址(数据链路层)。协议封装 数据包被封装…...
用 NGINX 打造高性能 FastCGI 加速 `ngx_http_fastcgi_module`
一、安装与启用 # 在编译 NGINX 源码时加上: ./configure --with-http_fastcgi_module make && sudo make install# 或确保你使用的二进制已内置(大多数发行版都默认包含) nginx -V | grep fastcgi二、基础转发配置 http {server {…...
深度学习 ———— 迁移学习
迁移学习原理 什么是迁移学习? 迁移学习利用在大规模数据集(如ImageNet)上预训练的模型,改装小数据集(如CIFAR-10)。优势: 减少训练时间:预训练模型已学习通用特征(如边…...

论文精读:YOLOE: Real-Time Seeing Anything
文章目录 前言1、背景2、方法2.1.重参Region-Text对齐模块2.2.VisualPrompt模块2.3.PromptFree 2.4.损失函数3、实验3.1.训练集3.2.实验结果 总结 前言 本文介绍一篇来自清华的开放词汇检测论文:YOLOE;源码链接。 1、背景 本文在yolo-world基础上&#x…...

以影像为笔,劳润智在世界舞台上书写艺术之路
在光影交织中,摄影师劳润智的镜头仿佛能穿透喧嚣,捕捉人类情感最细腻的脉动。从疫情下洛杉矶裁缝日常的温馨瞬间,到象征自由与解脱的飞鸟影像,再到探索时间与空间交错的抽象作品,每一幅作品都展现了他对艺术的深度追求与对生活的温柔洞察。 劳润智的作品为他赢得了多个国际奖项…...
vue3 computed方法传参数
我们对computed的基础用法不陌生,比如前端项目中经常会遇到数据处理的情况,我们就会选择computed方法来实现。但大家在碰到某些特殊场景,比如在template模板中for循环遍历时想给自己的计算属性传参,这个该怎么实现呢,很…...
【ES】Elasticsearch字段映射冲突问题分析与解决
在使用Elasticsearch作为搜索引擎时,经常会遇到一些映射(Mapping)相关的问题。本文将深入分析字段映射冲突问题,并通过原生的Elasticsearch API请求来复现和解决这个问题。 问题描述 在实际项目中,我们遇到以下错误: Transport…...
昇腾NPU容器内 apt 换源
环境 昊算NPU云910b 问题 缺少vim等,同时无法apt安装新的依赖 解决办法 使用vi修改/etc/apt/sources.list.d/debian.sources Types: deb URIs: http://deb.debian.org/debian Suites: bookworm bookworm-updates bookworm-backports Components: main contrib…...
MySQL 从入门到精通(五):索引深度解析 —— 性能优化的核心武器
目录 一、索引概述:数据库的 “目录” 1.1 什么是索引? 1.2 索引的性能验证:用事实说话 实验环境准备 无索引查询耗时 有索引查询耗时 索引的 “空间换时间” 特性 二、索引的创建:三种核心方式 2.1 方式 1:C…...
spark-Join Key 的基数/rand函数
在数据处理中,Join Key 的基数 是指 Join Key 的唯一值的数量(也称为 Distinct Key Count)。它表示某个字段(即 Join Key)在数据集中有多少个不同的值。 1. Join Key 基数的意义 高基数:Join Key 的唯一值…...

LLMs之ChatGPT:《Connecting GitHub to ChatGPT deep research》翻译与解读
LLMs之ChatGPT:《Connecting GitHub to ChatGPT deep research》翻译与解读 导读:这篇OpenAI帮助文档全面介绍了将GitHub连接到ChatGPT进行深度代码研究的方法、优势和注意事项。通过连接GitHub,用户可以充分利用ChatGPT强大的代码理解和生成…...

【桌面】【输入法】常见问题汇总
目录 一、麒麟桌面系统输入法概述 1、输入法介绍 2、输入法相关组件与服务 3、输入法调试相关命令 3.1、输入法诊断命令 3.2、输入法配置重新加载命令 3.3、启动fcitx输入法 3.4、查看输入法有哪些版本,并安装指定版本 3.5、重启输入法 3.6、查看fcitx进程…...
R语言学习--Day01--数据清洗初了解andR的经典筛选语法
当我们在拿到一份数据时,是否遇到过想要分析数据却无从下手?通过编程语言去利用它时发现有很多报错不是来源于代码而是因为数据里有很多脏数据;在这个时候,如果你会用R语言来对数据进行清洗,这会让你的效率提升很多。 …...

QT的初始代码解读及其布局和弹簧
this指的是真正的当前正在显示的窗口 main函数: Widget w是生成了一个主窗口,QT Designer是在这个主窗口里塞组件 w.show()用来展示这个主窗口 头文件: namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一个东西 Ui…...

Profinet转CanOpen网关,打破协议壁垒的关键技术
在石油化工行业的生产现场,各类自动化设备如同精密运转的神经系统,而通信协议则是传递信号的"语言"。当不同厂商的设备采用Canopen与Profinet这两种主流工业协议时,就像两个使用不同方言的专家需要实时协作,此时开疆智能…...

引用第三方自定义组件——微信小程序学习笔记
1. 使用 npm 安装第三方包 1.1 下载安装Node.js 工具 下载地址:Node.js — Download Node.js 1.2 安装 npm 包 在项目空白处右键弹出菜单,选择“在外部终端窗口打开”,打开命令行工具,输入以下指令: 1> 初始化:…...
Docker、Docker-compose、K8s、Docker swarm之间的区别
1.Docker docker是一个运行于主流linux/windows系统上的应用容器引擎,通过docker中的镜像(image)可以在docker中构建一个独立的容器(container)来运行镜像对应的服务; 例如可以通过mysql镜像构建一个运行mysql的容器,既可以直接进入该容器命…...

SpringAI实现AI应用-使用redis持久化聊天记忆
SpringAI实战链接 1.SpringAl实现AI应用-快速搭建-CSDN博客 2.SpringAI实现AI应用-搭建知识库-CSDN博客 3.SpringAI实现AI应用-内置顾问-CSDN博客 4.SpringAI实现AI应用-使用redis持久化聊天记忆-CSDN博客 5.SpringAI实现AI应用-自定义顾问(Advisor)…...