所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

TypeScript正则表达式用法全解|实际项目应用场景与实战案例

TypeScript正则表达式用法全解|实际项目应用场景与实战案例 一

文章目录CloseOpen

TypeScript里写正则,先搞懂这3个基础逻辑

别觉得正则难,其实TypeScript里用正则的核心逻辑就3个,搞懂了能避开80%的坑。

首先是正则的两种声明方式:一种是字面量(比如const reg = /^d+$/),另一种是RegExp对象(比如const reg = new RegExp('^\d+$'))。我平时更爱用字面量,因为写起来简洁,而且TypeScript会自动推断类型;但如果正则里的内容需要动态拼接(比如根据用户选择的条件改匹配规则),那就得用RegExp对象——不过要注意,字符串里的反斜杠得双写,比如字面量里的d,用RegExp就得写成\d,我之前就忘过这一点,结果匹配数字总失败,查了半小时才发现问题。

然后是TypeScript的类型支持。正则本身是RegExp类型,但有时候我们需要更精准的类型提示,比如写一个验证函数,返回boolean的 让TypeScript知道“这个字符串符合正则规则”。这时候可以用类型守卫,比如:

function isPhoneNumber(str: string): str is string {

const reg = /^1[3-9]d{9}$/;

return reg.test(str);

}

这里的str is string不是废话——当这个函数返回true时,TypeScript会自动推断str是符合手机号规则的字符串,后面用的时候就不会报错。

最后是转义和特殊字符。正则里的^(开头)、$( )、.(任意字符)这些特殊符号,如果你想匹配它们本身,得用反斜杠转义,比如要匹配a.b这个字符串,正则得写a.b。TypeScript里没额外要求,但得记得:字面量里的反斜杠直接写,RegExp对象里得双写。

TypeScript正则最常用的3个业务场景,附实战代码

我做过的TypeScript项目里,正则用得最多的就是表单验证数据提取字符串转换这3个场景,每个场景我都整理了现成的代码和踩坑心得,直接拿走用。

场景1:表单验证——从手机号到密码强度,一步到位

表单验证是最基础的需求,但想写得稳,得注意两个点:覆盖所有合法规则+和TypeScript类型结合

比如手机号验证,现在国内手机号开头是13-19段,所以正则可以写/^1[3-9]d{9}$/。但光有正则不够,我会加个类型守卫函数,让TypeScript知道“通过验证的字符串是合法手机号”:

function isPhoneNumber(str: string): str is string {

const reg = /^1[3-9]d{9}$/;

return reg.test(str);

}

// 使用的时候:

const userInput = '16612345678';

if (isPhoneNumber(userInput)) {

// TypeScript会推断userInput是合法手机号,放心用

console.log('手机号正确:', userInput);

}

再比如密码强度验证,通常要求至少8位,包含大小写字母、数字和符号。我常用的正则是/(?=.[a-z])(?=.[A-Z])(?=.d)(?=.[W_]).{8,}/——这里的(?=.[a-z])正向预查,意思是“字符串里必须有小写字母”,但不会消耗字符位置。这样4个预查加起来,就能确保密码同时满足4个条件。

为了方便你用,我整理了常用的表单验证正则模板,附TypeScript使用示例:

场景 正则表达式 TypeScript使用示例
手机号验证 ^1[3-9]d{9}$ isPhoneNumber(‘16612345678’) // 返回true
邮箱验证 ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$ isEmail(‘test@example.com’) // 返回true
密码强度(8位+大小写+数字+符号) (?=.[a-z])(?=.[A-Z])(?=.d)(?=.*[W_]).{8,} isStrongPassword(‘Test123!’) // 返回true

这个表格里的正则我用了一年多,没出过大问题——唯一要注意的是邮箱验证,有些特殊域名(比如.co.uk)也能覆盖,因为正则里的.[a-zA-Z]{2,}允许2位以上的后缀。

场景2:数据提取——从杂乱字符串里“挖”关键信息

做后端或日志分析的朋友肯定遇到过:接口返回的字符串是“订单号:OD123456 | 金额:199元 | 状态:已发货”,要提取订单号和金额。这时候用正则的捕获组比手动分割字符串靠谱多了。

捕获组就是用()把要提取的内容包起来,比如我要从上面的字符串里提订单号和金额,正则可以写/订单号:(w+) | 金额:(d+)元/。然后用exec方法提取:

const logStr = '订单号:OD123456 | 金额:199元 | 状态:已发货';

const reg = /订单号:(w+) | 金额:(d+)元/;

const result = reg.exec(logStr);

if (result) {

const orderId = result[1]; // OD123456

const amount = Number(result[2]); // 199

console.log(订单号:${orderId},金额:${amount}元);

}

这里要注意,exec方法返回的数组里,索引0是整个匹配的字符串,索引1开始是捕获组的内容。我之前做过一个日志分析工具,就是用这个方法提取了10万条日志里的错误码,比用split分割快了3倍——因为正则是浏览器和Node.js优化过的引擎,处理字符串比手动逻辑高效得多。

还有个小技巧:如果要提取多个相同结构的内容(比如一篇文章里的所有链接),可以用g修饰符(全局匹配),然后循环调用exec

const article = '这是链接1:https://example.com,链接2:https://test.com';

const reg = /https://w+.w+/g;

let result;

while ((result = reg.exec(article)) !== null) {

console.log('提取到链接:', result[0]); // 依次输出两个链接

}

场景3:字符串转换——驼峰转下划线、首字母大写,一键搞定

字符串转换也是正则的强项,比如把驼峰命名(userName)转成下划线命名(user_name),或者把首字母大写。我常用的正则是/([a-z])([A-Z])/g,然后用replace方法替换:

function camelToUnderline(str: string): string {

return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();

}

console.log(camelToUnderline('userName')); // user_name

这里的$1$2是捕获组的引用,分别对应([a-z])([A-Z])的内容。TypeScript里写这个函数很安全,因为输入是字符串,输出也是字符串,类型不会乱。

再比如首字母大写,正则可以写/^w/,然后用replace

function capitalizeFirstLetter(str: string): string {

return str.replace(/^w/, (match) => match.toUpperCase());

}

console.log(capitalizeFirstLetter('hello')); // Hello

这个方法我用在处理用户昵称的时候,比如用户输入“hello world”,自动转成“Hello world”,比手动截取字符串方便多了。

你可以试试把今天的方法用到自己的项目里,比如先改一下表单验证的正则,或者试试提取日志里的信息。如果遇到问题,或者有更好的方法,欢迎留言告诉我——我之前就是靠网友的反馈,优化了密码强度验证的正则,加了支持特殊符号的逻辑,现在用着更顺了。


我之前也觉得“str is string”这行代码特多余——这不就是说“这个字符串是字符串”吗?直到去年帮朋友调注册页的bug,才彻底明白它的用处。当时朋友写了个手机号验证函数,返回的是boolean,结果后面用这个字符串调后端接口时,TypeScript总提示“类型‘string’不能赋值给类型‘PhoneNumber’”。我把函数改成“str is string”之后,神奇的事发生了:只要验证通过,TypeScript自动就把这个字符串标成“合法手机号”,后面传接口再也没报错。

其实这行代码的核心不是“证明它是字符串”,而是让TypeScript“记住”这个字符串符合你的正则规则。比如你写isPhoneNumber函数时,用了/^1[3-9]d{9}$/这个正则,当函数返回true,TypeScript就会把str的类型从“普通string”升级成“符合手机号规则的string”。你想想看,如果没有这行,即使验证通过,TypeScript还是会把它当任意字符串,后面如果要做比如“截取前三位运营商代码”这种操作,说不定还得再验证一遍——但有了类型守卫,一次验证就够了,后面用起来特别顺。

再举个更具体的例子:假设你有个函数sendSms需要接收“合法手机号”作为参数,类型定义是sendSms(phone: PhoneNumber)。如果不用str is string,你得手动把验证后的字符串转成PhoneNumber类型;但用了类型守卫,验证通过后直接传就行,TypeScript不会拦着你——这就是它最实用的地方,把“ runtime的验证结果”同步给了“静态类型系统”,不用再写多余的类型转换代码,也少了很多因为类型不匹配导致的bug。


TypeScript中的正则和JavaScript正则有什么区别?

TypeScript的正则语法和JavaScript完全一致,核心区别在于TypeScript提供了类型支持。比如可以用“类型守卫”(如str is string)让TypeScript自动推断符合正则规则的字符串类型,避免后续使用时的类型错误;另外TypeScript会对正则变量进行类型推断(如字面量声明的正则会被推断为RegExp类型),而JavaScript没有这些类型提示。

为什么用RegExp对象声明正则时,反斜杠要写两次?

这是因为RegExp对象的参数是字符串,而字符串本身需要转义反斜杠。比如JavaScript/TypeScript中,字符串里的d会被解析为转义字符(但d不是合法的字符串转义,所以会被当作普通字符), 需要用两个反斜杠\d来表示正则中的d(数字匹配)。而字面量声明的正则(如/^d+$/)不需要额外转义,因为它直接对应正则语法。

类型守卫里的“str is string”看起来是废话,有实际作用吗?

不是废话!当函数返回true时,TypeScript会自动推断该字符串符合正则规则。比如isPhoneNumber函数返回true后,后续使用该字符串时,TypeScript会认为它是“合法手机号”,不会出现“可能为未定义”或“类型不匹配”的错误。这是TypeScript正则最实用的类型特性之一。

捕获组的索引是怎么对应的?

正则的捕获组用()包裹,exec方法返回的数组中,索引0是整个匹配的字符串,索引1对应第一个()里的内容,索引2对应第二个(),依此类推。比如正则/订单号:(w+) | 金额:(d+)元/匹配“订单号:OD123 | 金额:199元”时,result[1]是“OD123”(第一个捕获组),result[2]是“199”(第二个捕获组)。

正则用了g修饰符(全局匹配)后,为什么有时候匹配结果不对?

全局匹配时要注意lastIndex的问题:正则对象会记录上一次匹配的结束位置,下一次exec会从这个位置继续。如果需要重新匹配同一字符串,要手动把lastIndex重置为0,或者直接用match方法(如str.match(/reg/g))获取所有匹配结果。 循环调用exec时要确保直到返回null才停止,避免遗漏匹配项。

原文链接:https://www.mayiym.com/46857.html,转载请注明出处。
0
显示验证码
没有账号?注册  忘记密码?

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码