C# 正则表达式完全指南
C# 正则表达式完全指南
C#通过 System.Text.RegularExpressions
命名空间提供强大的正则表达式支持。本指南将详细介绍C#中正则表达式的使用方法、性能优化和最佳实践。
1. 基础知识
1.1 命名空间导入
using System.Text.RegularExpressions;
1.2 基本使用
public class RegexBasics
{public void BasicExamples(){string text = "Hello, my phone is 123-456-7890";// 创建正则表达式对象Regex regex = new Regex(@"\d+");// 检查是否匹配bool isMatch = regex.IsMatch(text);// 查找第一个匹配Match match = regex.Match(text);if (match.Success){Console.WriteLine($"Found: {match.Value}");}// 查找所有匹配MatchCollection matches = regex.Matches(text);foreach (Match m in matches){Console.WriteLine($"Found: {m.Value}");}}
}
1.3 正则表达式选项
public class RegexOptions
{public void OptionsExample(){// 不区分大小写Regex caseInsensitive = new Regex(@"hello", RegexOptions.IgnoreCase);// 多行模式Regex multiline = new Regex(@"^start", RegexOptions.Multiline);// 忽略空白字符和注释Regex ignored = new Regex(@"\d+ # 匹配数字\s* # 可选的空白字符\w+ # 匹配单词", RegexOptions.IgnorePatternWhitespace);// 编译正则表达式以提高性能Regex compiled = new Regex(@"\d+", RegexOptions.Compiled);}
}
2. 正则表达式语法
2.1 字符匹配
public class CharacterMatching
{public void MatchingExamples(){string text = "C# 10.0 is awesome! Price: $99.99";// 匹配数字Regex digits = new Regex(@"\d+");foreach (Match m in digits.Matches(text)){Console.WriteLine($"Number: {m.Value}");}// 匹配单词Regex words = new Regex(@"\w+");var wordMatches = words.Matches(text).Cast<Match>().Select(m => m.Value).ToList();// 匹配空白字符string[] parts = Regex.Split(text, @"\s+");// 自定义字符类Regex vowels = new Regex(@"[aeiou]", RegexOptions.IgnoreCase);var vowelMatches = vowels.Matches(text).Cast<Match>().Select(m => m.Value).ToList();}
}
2.2 分组和捕获
public class GroupingExample
{public void GroupExamples(){string text = "John Smith, Jane Doe, Bob Johnson";// 基本分组Regex regex = new Regex(@"(\w+)\s(\w+)");foreach (Match match in regex.Matches(text)){Console.WriteLine($"Full name: {match.Groups[0].Value}");Console.WriteLine($"First name: {match.Groups[1].Value}");Console.WriteLine($"Last name: {match.Groups[2].Value}");}// 命名分组Regex namedRegex = new Regex(@"(?<first>\w+)\s(?<last>\w+)");foreach (Match match in namedRegex.Matches(text)){Console.WriteLine($"First: {match.Groups["first"].Value}");Console.WriteLine($"Last: {match.Groups["last"].Value}");}}
}
3. 高级特性
3.1 替换操作
public class ReplacementOperations
{public string ReplaceExample(string text){// 简单替换string result1 = Regex.Replace(text, @"\d+", "X");// 使用MatchEvaluator委托string result2 = Regex.Replace(text, @"\d+", match =>{int number = int.Parse(match.Value);return (number * 2).ToString();});// 使用命名组的替换Regex regex = new Regex(@"(?<first>\w+)\s(?<last>\w+)");string result3 = regex.Replace(text, "${last}, ${first}");return result3;}
}
3.2 前瞻和后顾
public class LookAroundExample
{public void LookAroundDemo(){string text = "Price: $100, Cost: $50";// 正向前瞻Regex positiveAhead = new Regex(@"\d+(?=\s*dollars)");// 负向前瞻Regex negativeAhead = new Regex(@"\d+(?!\s*dollars)");// 正向后顾Regex positiveBehind = new Regex(@"(?<=\$)\d+");// 负向后顾Regex negativeBehind = new Regex(@"(?<!\$)\d+");}
}
4. 实用工具类
4.1 验证器
public class Validator
{private static readonly Regex EmailRegex = new Regex(@"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",RegexOptions.Compiled);private static readonly Regex PhoneRegex = new Regex(@"^1[3-9]\d{9}$",RegexOptions.Compiled);private static readonly Regex PasswordRegex = new Regex(@"^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$",RegexOptions.Compiled);public static bool IsValidEmail(string email){if (string.IsNullOrEmpty(email)) return false;return EmailRegex.IsMatch(email);}public static bool IsValidPhone(string phone){if (string.IsNullOrEmpty(phone)) return false;return PhoneRegex.IsMatch(phone);}public static bool IsValidPassword(string password){if (string.IsNullOrEmpty(password)) return false;return PasswordRegex.IsMatch(password);}
}
4.2 文本处理器
public class TextProcessor
{private static readonly Regex UrlRegex = new Regex(@"https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[^\s]*",RegexOptions.Compiled);private static readonly Regex HtmlTagRegex = new Regex(@"<[^>]+>",RegexOptions.Compiled);public static IEnumerable<string> ExtractUrls(string text){if (string.IsNullOrEmpty(text)) return Enumerable.Empty<string>();return UrlRegex.Matches(text).Cast<Match>().Select(m => m.Value);}public static string StripHtmlTags(string html){if (string.IsNullOrEmpty(html)) return string.Empty;return HtmlTagRegex.Replace(html, string.Empty);}public static string CleanWhitespace(string text){if (string.IsNullOrEmpty(text)) return string.Empty;return Regex.Replace(text.Trim(), @"\s+", " ");}
}
5. 性能优化
5.1 静态编译正则表达式
public class RegexOptimization
{// 使用静态字段存储编译后的正则表达式private static readonly Regex CompiledRegex = new Regex(@"\d+",RegexOptions.Compiled);// 使用Lazy<T>延迟初始化private static readonly Lazy<Regex> LazyRegex = new Lazy<Regex>(() => new Regex(@"\d+", RegexOptions.Compiled));public void OptimizedExample(){// 使用编译后的正则表达式bool isMatch = CompiledRegex.IsMatch("123");// 使用延迟初始化的正则表达式bool lazyMatch = LazyRegex.Value.IsMatch("123");}
}
5.2 性能考虑
public class PerformanceConsiderations
{// 1. 使用适当的选项private static readonly Regex FastRegex = new Regex(@"\d+",RegexOptions.Compiled | RegexOptions.ExplicitCapture);// 2. 避免过度使用通配符private static readonly Regex BetterRegex = new Regex(@"[^/]*foo[^/]*", // 比 .*foo.* 更高效RegexOptions.Compiled);// 3. 使用非捕获组private static readonly Regex NonCapturingRegex = new Regex(@"(?:\d+)(?:[a-z]+)", // 使用(?:)表示非捕获组RegexOptions.Compiled);
}
6. 异常处理
public class RegexExceptionHandling
{public static Regex CreateSafeRegex(string pattern){try{return new Regex(pattern, RegexOptions.Compiled);}catch (ArgumentException ex){throw new ArgumentException($"Invalid regex pattern: {ex.Message}", ex);}}public static bool SafeIsMatch(string input, string pattern){try{return Regex.IsMatch(input, pattern);}catch (RegexMatchTimeoutException ex){Console.WriteLine($"Regex matching timed out: {ex.Message}");return false;}catch (ArgumentException ex){Console.WriteLine($"Invalid regex pattern: {ex.Message}");return false;}}
}
7. 单元测试
[TestClass]
public class ValidatorTests
{[TestMethod]public void TestEmailValidation(){Assert.IsTrue(Validator.IsValidEmail("test@example.com"));Assert.IsTrue(Validator.IsValidEmail("user@domain.co.uk"));Assert.IsFalse(Validator.IsValidEmail("invalid.email"));Assert.IsFalse(Validator.IsValidEmail("@domain.com"));}[TestMethod]public void TestPhoneValidation(){Assert.IsTrue(Validator.IsValidPhone("13812345678"));Assert.IsFalse(Validator.IsValidPhone("12345678"));Assert.IsFalse(Validator.IsValidPhone("2381234567"));}[TestMethod]public void TestTextProcessing(){string html = "<p>Hello</p><div>World</div>";Assert.AreEqual("HelloWorld",TextProcessor.StripHtmlTags(html));string text = " multiple spaces here ";Assert.AreEqual("multiple spaces here",TextProcessor.CleanWhitespace(text));}
}
总结
C#的正则表达式实现具有以下特点:
- 强大的Regex类支持
- 编译选项提供高性能
- LINQ集成
- 完整的Unicode支持
最佳实践:
- 使用静态编译的Regex对象提高性能
- 合理使用RegexOptions
- 处理超时和异常情况
- 编写完整的单元测试
- 使用命名捕获组提高可读性
注意事项:
- Regex对象创建开销大,应该重用
- 考虑使用Compiled选项提高性能
- 处理RegexMatchTimeoutException
- 注意内存使用
记住:在C#中使用正则表达式时,要充分利用.NET框架提供的功能,如编译选项和LINQ集成。合理使用静态编译和缓存可以显著提高性能。
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
C# 正则表达式完全指南
C# 正则表达式完全指南 C#通过 System.Text.RegularExpressions 命名空间提供强大的正则表达式支持。本指南将详细介绍C#中正则表达式的使用方法、性能优化和最佳实践。 1. 基础知识 1.1 命名空间导入 using System.Text.RegularExpressions;1.2 基本使用 public class Re…...
![](https://www.ngui.cc/images/no-images.jpg)
【笔记整理】记录参加骁龙AIPC开发者技术沙龙的笔记
AIoT 首先了解了一个概念叫AIoT,我的理解就是AI IoT 5G,通过AI的发展使得边缘计算、数据整合和处理变得快捷方便,不仅限于传统的云端数据处理,在边缘的IoT设备上也可以进行智能化打造,通过5G的通信能力扩展可以实现…...
![](https://i-blog.csdnimg.cn/img_convert/b3e6bd974e77167e053f0db5acf5c160.png)
论文解析 | 基于语言模型的自主代理调查
论文 《A Survey on Large Language Model-based Autonomous Agents》 对基于大型语言模型(LLM)的自主智能体(Autonomous Agents)进行了全面调查。随着大型语言模型(如 GPT 系列、BERT、T5 等)的快速发展&a…...
![](https://www.ngui.cc/images/no-images.jpg)
面试加分项:Android Framework AMS 全面概述和知识要点
第一章:AMS 的架构与组件 1.1 AMS 整体架构 在 Android 系统的庞大体系中,AMS(Activity Manager Service)就如同一个中枢神经系统,是整个系统的核心服务之一,对应用的性能和用户体验有着直接且关键的影响 。它的整体架构由 Client 端和 Service 端两大部分组成,这两端相…...
![](https://i-blog.csdnimg.cn/direct/4b0726f4aa0a4187b3f1ddbd6a72c19b.png)
EasyCVR视频汇聚平台如何配置webrtc播放地址?
EasyCVR安防监控视频系统采用先进的网络传输技术,支持高清视频的接入和传输,能够满足大规模、高并发的远程监控需求。平台支持多协议接入,能将接入到视频流转码为多格式进行分发,包括RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、W…...
![](https://www.ngui.cc/images/no-images.jpg)
用户界面软件04
后果 使用这种架构很容易对两个层面的非功能性需求进行优化,但是你仍然需要小心不要将功能 需求重复实现。 现在,两个层面可能有完全不同的设计。比如,用户界面层可能使用配件模型(Widget Model), 以大量的…...
![](https://i-blog.csdnimg.cn/blog_migrate/5bbecffd3885e7542d976c48472ad554.png)
C#,数值计算,矩阵相乘的斯特拉森(Strassen’s Matrix Multiplication)分治算法与源代码
Volker Strassen 1 矩阵乘法 矩阵乘法是机器学习中最基本的运算之一,对其进行优化是多种优化的关键。通常,将两个大小为N X N的矩阵相乘需要N^3次运算。从那以后,我们在更好、更聪明的矩阵乘法算法方面取得了长足的进步。沃尔克斯特拉森于1…...
![](https://i-blog.csdnimg.cn/direct/4db68abbdb244836a6632b5a3b96b776.png)
linux:文件的创建/删除/复制/移动/查看/查找/权限/类型/压缩/打包
关于文件的关键词 创建 touch 删除 rm 复制 cp 权限 chmod 移动 mv 查看内容 cat(全部); head(前10行); tail(末尾10行); more,less 查找 find 压缩 gzip ; bzip 打包 tar 编辑 sed 创建文件 格式: touch 文件名 删除文件 复制文件 移动文件 查看文…...
![](https://www.ngui.cc/images/no-images.jpg)
SQL Server查询计划操作符——查询计划相关操作符(3)
7.3. 查询计划相关操作符 19)Collapse:该操作符对更改处理进行优化。当执行一个更改时,其能被劈成(用Split操作符)一个删除和一个插入。其参数列包含一个确定一系列键值字段的GROUP BY:()子句。如果查询处理器遇到删除和插入相同键值的毗邻行,其将用一个更高效的更改操作…...
![](https://i-blog.csdnimg.cn/direct/a7e5d493ae4c43e2ac957ec5becc0f51.png)
【Notepad++】Notepad++如何删除包含某个字符串所在的行
Notepad如何删除包含某个字符串所在的行 一,简介二,操作方法三,总结 一,简介 在使用beyoundcompare软件进行对比的时候,常常会出现一些无关紧要的地方,且所在行的内容是变化的,不方便进行比较&…...
![](https://www.ngui.cc/images/no-images.jpg)
Android 来电白名单 只允许联系人呼入电话
客户需求只允许通讯录中联系人可以呼入电话。参考自带的黑名单实现 CallsManager.java类中的onSuccessfulIncomingCall方法有一些过滤器,可以仿照黑名单的方式添加自己的过滤器。 packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java …...
![](https://i-blog.csdnimg.cn/blog_migrate/c6909aecbcc13d601e65c093ad0ee5d7.gif)
【计算机网络】lab3 802.11 (无线网络帧)
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀计算机网络_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2.…...
![](https://i-blog.csdnimg.cn/direct/445d92691c6d4db5bcb84fd0f356cbfc.png)
单片机(MCU)-简单认识
简介: 内部集成了CPU,RAM,ROM,定时器,中断系统,通讯接口等一系列电脑的常用硬件功能。 单片机的任务是信息采集(依靠传感器),处理(依靠CPU)&…...
![](https://i-blog.csdnimg.cn/direct/2f6e80576dd24347a31b4edc18500638.png)
全面教程:Nacos 2.3.2 启用鉴权与 MySQL 数据存储配置
全面教程:Nacos 2.3.2 启用鉴权与 MySQL 数据存储配置 1. 配置 Nacos 开启鉴权功能 1.1 修改 application.properties 配置文件 在 Nacos 2.3.2 中,开启鉴权功能需要修改 conf/application.properties 文件。按照以下方式配置: # 开启鉴权…...
![](https://i-blog.csdnimg.cn/img_convert/15c3261df22d346fd2c25840c29695e3.webp?x-oss-process=image/format,png)
软件23种设计模式完整版[附Java版示例代码]
一、什么是设计模式 设计模式是在软件设计中反复出现的问题的通用解决方案。它们是经过多次验证和应用的指导原则,旨在帮助软件开发人员解决特定类型的问题,提高代码的可维护性、可扩展性和重用性。 设计模式是一种抽象化的思维方式,可以帮助开发人员更好地组织和设计他们…...
![](https://i-blog.csdnimg.cn/img_convert/40d449e31c49ec5d2d6c5a53f9896d53.png)
国标GB28181-2022视频平台EasyGBS小知识:局域网ip地址不够用怎么解决?
在局域网中,IP地址不足的问题通常不会在小型网络中出现,但在拥有超过255台设备的大型局域网中,就需要考虑如何解决IP地址不够用的问题了。 在企业局域网中,经常会出现私有IP地址如192.168.1.x到192.168.1.255不够用的情况。由于0…...
![](https://www.ngui.cc/images/no-images.jpg)
PHP 循环控制结构深度剖析:从基础到实战应用
PHP 循环控制结构深度剖析:从基础到实战应用 PHP提供了多种控制结构,其中循环控制结构是最常见的结构之一。它们使得我们能够高效地重复执行一段代码,直到满足某个条件为止。本文将从PHP循环的基础知识出发,逐步分析其在实际项目…...
![](https://i-blog.csdnimg.cn/direct/32e7e880ecec469fbf4441f0672bef23.png)
vue的属性绑定
重建一个新的项目 App.vue main.js HelloWorld.vue 属性绑定 双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令 <template><div v-bind:id"dynamicId" v-bind:class"dynamicClass">…...
![](https://i-blog.csdnimg.cn/direct/3f42b570e68c4e2db4493b08d5063c1d.png#pic_center)
FFmpeg音视频流媒体,视频编解码性能优化
你是不是也有过这样一个疑问:视频如何从一个简单的文件变成你手机上快速播放的短片,或者是那种占满大屏幕的超高清大片?它背后的法宝,离不开一个神奇的工具——FFmpeg!说它强大,完全不为过,它在…...
![](https://www.ngui.cc/images/no-images.jpg)
16_Redis Lua脚本
Redis Lua脚本是Redis提供的一种强大的扩展机制。 1.Redis Lua脚本介绍 1.1 基本概念 Redis Lua脚本允许开发者将一段Lua语言编写的代码发送给Redis服务器执行。这项功能自Redis 2.6版本引入以来,为用户提供了强大的灵活性和扩展能力,使得可以在Redis内部直接处理复杂的业…...
![](https://i-blog.csdnimg.cn/direct/e34adf8c330541118fae395edec67d83.png)
Redis为 List/Set/Hash 的元素设置单独的过期时间
一.业务简介 我们知道,Redis 里面暂时没有接口给 List、Set 或者 Hash 的 field 单独设置过期时间,只能给整个列表、集合或者 Hash 设置过期时间。 这样,当 List/Set/Hash 过期时,里面的所有 field 元素就全部过期了。但这样并不…...
![](https://www.ngui.cc/images/no-images.jpg)
鸿蒙中调整应用内文字大小
1、ui Stack() {Row() {ForEach([1, 2, 3, 4], (item: number) > {Text().width(3).height(20).backgroundColor(Color.Black).margin(item 2 ? { left: 8 } : item 3 ? { left: 7 } : { left: 0 })})}.width(97%).justifyContent(FlexAlign.SpaceBetween).padding({ ri…...
![](https://www.ngui.cc/images/no-images.jpg)
计算机网络之---防火墙与入侵检测系统(IDS)
防火墙与入侵检测系统(IDS) 防火墙(Firewall) 和 入侵检测系统(IDS, Intrusion Detection System) 都是网络安全的关键组件,但它们的作用、功能和工作方式有所不同。 防火墙 防火墙是网络安全的一种设备或软件&#…...
![](https://i-blog.csdnimg.cn/direct/2d302af3de3f44dcb3c3482c3273e779.png)
KG-CoT:基于知识图谱的大语言模型问答的思维链提示
一些符号定义 知识图谱实体数量: n n n 知识图谱中关系类型数量: m m m 三元组矩阵: M ∈ { 0 , 1 } n n m \textbf{M} \in \{0, 1\}^{n \times n \times m} M∈{0,1}nnm, M i j k 1 M_{ij}^k 1 Mijk1则说明实体 i i i和实…...
![](https://www.ngui.cc/images/no-images.jpg)
【JMeter】多接口关联
1. 同一线程组内,如何实现多接口关联 非加密的值 前置接口的返回单条数据使用Json提取器提取前置接口的返回多条数据使用Json提取器+逻辑控制器Loop Controller前置接口的返回多条数据使用Json提取器+逻辑控制器forEach加密的值 前置接口的返回值使用Beanshell后置提取器存储为…...
![](https://www.ngui.cc/images/no-images.jpg)
2020 年 12 月青少年软编等考 C 语言五级真题解析
目录 T1. 漫漫回国路思路分析T2. 装箱问题思路分析T3. 鸣人和佐助思路分析T4. 分成互质组思路分析T1. 漫漫回国路 2020 年 5 月,国际航班一票难求。一位在美国华盛顿的中国留学生,因为一些原因必须在本周内回到北京。现在已知各个机场之间的航班情况,求问他回不回得来(不考…...
![](https://www.ngui.cc/images/no-images.jpg)
前端实时显示当前在线人数的实现
实时显示当前在线人数的实现 本文档提供了在网页上实时显示当前在线人数的多种实现方法,包括使用 WebSocket 实现实时更新和轮询方式实现非实时更新。 方法一:使用 WebSocket 实现实时更新 服务器端设置 通过 Node.js 和 WebSocket 库(如 …...
![](https://i-blog.csdnimg.cn/direct/aa90735fb08942909e82d821074aa0b3.png)
Linux第一个系统程序---进度条
进度条---命令行版本 回车换行 其实本质上回车和换行是不同概念,我们用一张图来简单的理解一下: 在计算机语言当中: 换行符:\n 回车符:\r \r\n:回车换行 这时候有人可能会有疑问:我在学习C…...
![](https://i-blog.csdnimg.cn/direct/368f68deb2674a069d2e89a429cf86e1.png)
vscode 无法使用npm, cmd命令行窗口可以正常执行
解决方法: 执行命令获得命令的位置 get-command npm 得到如下 然后删除或者修改 npm.ps1文件 让其不能使用就行。然后重启vscode即可。 pnpm 同理即可 另外加速源 国内镜像源(淘宝): npm config set registry https://regist…...
![](https://www.ngui.cc/images/no-images.jpg)
Leetcode 967 Numbers With Same Consecutive Differences
题意 给定n,代表整数的长度,给定k代表两个相邻数字之间的间隔。求所有的值构成的组合 题目链接 https://leetcode.com/problems/numbers-with-same-consecutive-differences/description/ 题解 dfs,有k位置要选,第一个位置我…...
![](/images/no-images.jpg)
创意设计公司业务范围/长沙seo研究中心
写两个线程,一个线程打印1-52,另一个线程打印A-Z,打印顺序是12A34B…5152Z 解题思路: 根据打印顺序我们可以看到是两个数字一个大写字母为一个循环;明确循环后要保证两个线程是交替进行(且打印数字在前&a…...
![](/images/no-images.jpg)
哪些网站免费注册企业域名/百度搜索广告投放
Oracle存储过程使用动态SQL 有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者。 DDL和DML (注意DDL中可以用拼接字符串的方法用来create table或drop table,在DML中,类似于insert则不可以直接用execute imme…...
![](https://img-blog.csdnimg.cn/2022010710192087526.png)
宁波哪里可以做网站/百度网盘网页版入口官网
1. 表的基本概念 在数据库中,表是一种非常重要的数据库对象,是组成数据库的基本对象,由若干个字段组成,主要用来储存数据记录。 表中的数据库对象包含列,索引和触发器。 列:也称属性列,在具体创建表时必须指定列的名字和数据类型。 索引:是根据指定的数据库表列建立…...
![](/images/no-images.jpg)
抖音小店代运营/seo网站推广主要目的不包括
1)无法下发指令 发现是因为加载下发指令的xml文件在发布状态下没有权限, 这个在vs上调试没有问题 ,发布后才发现新问题。 2)无法实时查看运行状况 vs2017无法直接调试js,上次成功也好像是偶然,所以只能…...
![](https://img-blog.csdnimg.cn/img_convert/82a270643703b451a72aabe4c4d77570.png)
四川网站备案/网络工程师是干什么的
对于编程初学者来说会接触到一些难以理解的名称,比如堆(heap)、栈(stack)、堆栈(stack)等。初学开发过程中往往让人混淆不清。今天我们来谈谈堆和栈的具体区别,来帮助初学者理清思路。堆和栈的区别一直都是永恒的话题,为此笔者也查了很多的资…...
![](https://img-blog.csdnimg.cn/2e9fc54717734a46afda9f620774670a.png)
成都住房和城乡建设厅网站/如何广告推广
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...