C#高级编程笔记--字符串和正则表达式

本章的主要内容如下:

  •         创建字符串
  •         格式化表达式
  •         正则表达式​​​​​​​

1.1   System.String类

System.String是一个类,专门用于存储字符串,允许对字符串进行许多操作。由于这种数据类型非常重要,C#提供了它自己的关键字和相关的语法,以便于使用这个类来处理字符串。

使用运算符重载可以连接字符串

string message1 = "Hello";  //return "Hello"

message1 += ", There";    // return "Hello, There "

string message2 = message1 + "!";     // return "Hello, There!"

C#还允许使用类似于索引器的语法来提取指定的字符:

char char4 = message[4];   // returns 'a'. Note the char is zero-indexed


这个类可以完成许多常见的任务,例如替换字符、删除空白和把字母变成大写形式等。可用的方法如表1-1所示。

1.1.1  创建字符串

如上所述,string类是一个功能非常强大的类,它执行许多很有用的方法。但是,string类存在一个问题:重复修改给定的字符串,效率会很低,它实际上是一个不可变的数据类型,一旦对字符串对象进行了初始化,该字符串对象就不能改变了。表面上修改字符串内容的方法和运算符实际上是创建一个新的字符串,如果必要,可以把旧字符串的内容复制到新字符串中。例如,下面的代码:

string greetingText = "Hello from all the guys at Wrox Press. ";

greetingText += "We do hope you enjoy this book as much as we enjoyed writing it.";

因为由于字符串的本质还是char数组,一旦初始化了也就代表数组的长度固定了,无法动态扩容,所以是一个不可变的数据类型。这里抛出一个问题:为什么字符串设计为不可变的数据类型?

为了解决这个问题,Microsoft提供了System.Text.StringBuilder类。StringBuilder不像String那样支持非常多的方法。在StringBuilder上可以进行的处理仅限于替换和添加或删除字符串中的文本。但是,它的工作方式非常高效。

在使用String类构造一个字符串时,要给它分配足够的内存来保存字符串,但StringBuilder通常分配的内存会比需要的更多。开发人员可以选择显式指定StringBuilder要分配多少内存,但如果没有显式指定,存储单元量在默认情况下就根据StringBuilder初始化时的字符串长度来确定。它有两个主要的属性:

●       Length指定字符串的实际长度;

●       Capacity是字符串占据存储单元的最大长度。

对字符串的修改就在赋予StringBuilder实例的存储单元中进行,这就大大提高了添加子字符串和替换单个字符的效率。删除或插入子字符串仍然效率低下,因为这需要移动随后的字符串。只有执行扩展字符串容量的操作,才需要给字符串分配新内存,才可能移动包含的整个字符串。在添加额外的容量时,从经验来看,StringBuilder如果检测到容量超出,且容量没有设置新值,就会使自己的容量翻倍。

注意:为了使用StringBuilder类,需要在代码中引用System.Text。一般,使用StringBuilder可以执行字符串的操作,String可以存储字符串或显示最终结果。

1.1.2  StringBuilder成员

StringBuilder的构造函数:

StringBuilder greetingBuilder =  new StringBuilder("HelloWorld. ", 150);

或者,可以只提供一个字符串:

StringBuilder sb = new StringBuilder("Hello");

或者用给定的容量创建一个空的StringBuilder:

StringBuilder sb = new StringBuilder(20);

除了前面介绍的Length 和 Capacity属性外,还有一个只读属性MaxCapacity,它表示对给定的StringBuilder实例的容量限制。在默认情况下,这由int.MaxValue给定(大约20亿,如前所述)。但在构造StringBuilder对象时,也可以把这个值设置为较低的值:

// This will both set initial capacity to 100, but the max will be 500.

StringBuilder sb = new StringBuilder(100, 500);

还可以随时显式地设置容量,但如果把这个值设置为低于字符串的当前长度,或者超出了最大容量,就会抛出一个异常:

StringBuilder sb = new StringBuilder("Hello");

sb.Capacity = 100;

主要的StringBuilder方法如表1-2所示。

注意:

AppendFormat()实际上会在调用Console.WriteLine()时调用,它负责确定所有像{0:D}的格式化表达式应使用什么表达式替代。下一节讨论这个问题。

不能把StringBuilder转换为String(隐式转换和显式转换都不行)。如果要把StringBuilder的内容输出为String,唯一的方式是使用ToString()方法。

前面介绍了StringBuilder类,说明了使用它提高性能的一些方式。注意,这个类并不总能提高性能。StringBuilder类基本上应在处理多个字符串时使用。但如果只是连接两个字符串,使用System.String会比较好。

1.2  字符串格式

C# 6引入了给字符串使用$前缀的字符串插值。下面的示例使用$前缀创建了字符串s2,这个前缀允许在花括号中包含占位符来引用代码的结果。{s1}是字符串中的一个占位符,编译器将变量s1的值放在字符串s2中.

string s1 = "world";

string s2 = $" hello, {s1} "

在现实中,这只是语法糖。对于带S前缀的字符串用。所以这段代码解读为:   

string s1 = "world";

string s2 = string.Format(" hello, {0} ",s1 )    

String.Format方法的第一个参数接受一个格式字符串,其中的占位符从0开始编号,其后是放入字符串空白处的参数。

新的字符串格式要方便得多,不需要编写那么多代码。不仅可以使用变量来填写字符串的空白处,还可以使用返回一个值的任何方法:

string s2 =$"Hello,(s1.ToUpper()}"; //string s2=String.Format("Hello,{0}",sl.ToUpper());

1. FormattableString

把字符串赋予FormattableString,就很容易得到翻译过来的插值字符串。插值字符串可以直接分配,因为 FormattableString比正常的字符串更适合匹配。这个类型定义了Format属性(返回得到的格式字符串)、 ArgumentCount属性和方法GetArgument(返回值):

intx=3,y=4;
Console.WriteLine(S"format:(s.Format}");
for(int i=0;i< s.ArgumentCount;i++)
Console.WriteLine($"argument (i}:(s.GetArgument(i)}");


//运行此代码段,输出结果如下:
format:The result of{0} +{l}is{2}
argument 0:3
argument 1:4
argument 2:7

注意:
类FormattableString在System名称空间中定义,但是需要.NET4.6。如果想在.NET旧版本中使用
FormattableString,可以自己创建这种类型,或使用NuGet包StringInterpolationBridge。

2. 给字符串插值使用其他区域值

插值字符串默认使用当前的区域值,这很容易改变。辅助方法Invariant把插值字符串改为使用不变的区域值,而不是当前的区域值。因为插值字符串可以分配给FormattableString类型,所以它们可以传递给这个方法。FormattableString定义了允许传递IFormatProvider的ToString方法。接口IFormatProvider由CultureInfo类实现。把 CultureInfo.InvariantCulture传递给IFormatProvider参数,就可把字符串改为使用不变的区域值:

private string Invariant(FormattableString s) => ToString(CultureInfo.InvariantCulture):

在下面的代码段中,Invariant方法用来把一个字符串传递给第二个WriteLine方法。WriteLine 的第一个调用使用当前的区域值,而第二个调用使用不变的区域值:

var day = new DateTime(2025,2,14);
Console.WriteLine($"{day:d}");
Console.WriteLine(Invariant($"{day:d}"));

如果有英语区域值设置,结果就如下所示。如果系统配置了另一个区域值,第一个结果就是不同的。在任何情况下,都会看到不变区域值的差异:

2/14/2025
02/14/2015

使用不变的区域值,不需要自己实现方法,而可以直接使用FormattableString 类的静态方法Invariant:

Console.WriteLine(FormattableString.Invariant($"(day:d}"));

3. 转义花括号

如果希望在插值字符串中包括花括号,可以使用两个花括号转义它们:

String S = "Hello";
Console.WriteLine($"{(s}} displays the value of s: {s}");

// 输出如下:
{s}displays thevalue of s:Hello

1.2.2日期时间和数字的格式

除了给占位符使用字符串格式之外,还可以根据数据类型使用特定的格式。下面先从日期开始。在占位符中,格式字符串跟在表达式的后面,用冒号隔开。下面所示的例子是用于DateTime类型的D和d格式:

var day=newDateTime(2025,2,14);
WriteLine($"{day:D}");
WriteLine($"(day:d}");
//  结果显示,用大写字母D表示长日期格式字符串,用小写字母d表示短日期字符串:
Friday, February 14, 2025
2/14/2025

根据所使用的大写或小写字符串,DateTime类型会得到不同的结果。根据系统的语言设置,输出可能不同。日期和时间是特定于语言的
DateTime类型支持很多不同的标准格式字符串,显示日期和时间的所有表示:例如,t表示短时间格式,T表示长时间格式,g和G显示日期和时间。这里不讨论所有其他选项,在MSDN文档的DateTime类型的ToString方法中,可以找到相关介绍。

这里抛出一个问题:如何定义自定义的日期格式字符串?

数字的格式字符串不区分大小写。下面看看n、e、x和c标准数字格式字符串:

inti=2477;
Console.WriteLine($"{i:n}{i:e}{i:x}{i:c}");
//输出:2,477.00 2.477000e+003 9ad $2,477.00

n格式字符串定义了一个数字格式,用组分隔符显示整数和小数。e表示使用指数表示法,x表示转换为十六进制,c显示货币:
对于数字的表示,还可以使用定制的格式字符事。#格式说明符是一个数字占位符,如果数字可用,就显示数字;如果数字不可用,就不显示数字。0格式说明符是一个零占位符,显示相应的数字,如果数字不存在,就显示零。

1.2.3 自定义字符串格式

格式字符串不限于内置类型,可以为自己的类型创建自定义格式字符串。为此,只需要实现接口 IFormattable。

首先是一个简单的Person类,它包含FirstName和LastName属性:

public class Person
{
    public string FirstName { get;set };
    public string LastName { get;set };

    public override string Tostring() => FirstName + "" + LastName;
}

为了获得这个类的简单字符串表示,重写基类的ToString方法。这个方法返回由FirstName和LastName组成的字符串。

除了简单的字符串表示之外,Person类也应该支持格式字符串F,返回名L和姓A,后者代表“all”;并且应该提供与ToString方法相同的字符串表示。为实现自定义字符串,接口IFormattable定义了带两个参数的 ToString方法:一个是格式的字符串参数,另一个是FormatProvider参数。FormatProvider参数未在示例代码中使用。可以基于区域值使用这个参数,进行不同的显示,因为CultureInfo类实现了该接口。

实现了这个接口的其他类是NumberFormatInfo和DateTimeFormatInfo.。可以把实例传递到ToString方法的第二个参数,使用这些类配置数字和DateTime的字符串表示。ToString方法的实现代码只使用switch语句,基于格式字符串返回不同的字符串。为了使用格式字符串直接调用ToString方法,而不提供格式提供程序,应重载ToString方法。这个方法又调用有两个参数的ToString方法:

public class Person:IFormattable{
    public string FirstName { get;set };
    public string LastName { get;set };
    public override string Tostring()=> FirstName + "" + LastName;
    public virtual string Tostring(string format)=>Tostring (format,null);
    public string Tostring(string format,IFormatProvider formatProvider){
        switch (format){
            case null:
            case "A":
                return Tostring();
            case "F":
                return FirstName;
            case "L":
                return LastName;
            default:
                throw new FormatException ($"invalid format string {format}");
        }
    }
}

有了这些代码,就可以显式传递格式字符串,或隐式使用字符串插值,以调用ToString方法。隐式的调用使用带两个参数的ToString方法,并给FormatProvider参数传递null。

var p1 =  new Person { FirstName = "Stephanie", LastName = "Nagel" };
Console.WriteLine (p1.Tostring ("F"));
Console.WriteLine ($"{p1:F)");

1.3  正则表达式

正则表达式作为小型技术领域的一部分,在各种程序中都有着难以置信的作用,但并不是所有的开发人员都知道这一点。正则表达式可以看做一种有特定功能的小型编程语言:在大的字符串表达式中定位一个子字符串。它不是一种新技术,最初它是在UNIX环境中开发的,与Perl和JavaScript编程语言一起使用得比较多。Microsoft把它移植到Windows中,到目前为止在脚本语言中用得比较多。但System. Text.RegularExpressions命名空间中的许多.NET类都支持正则表达式。.NET Framework的各个部分都使用正则表达式,例如,在ASP.NET的验证服务器控件中就使用了正则表达式。

注意,.NET正则表达式引擎是为兼容Perl 5的正则表达式而设计的,但有一些新特性。
使用正则表达式,可以对字符串执行许多复杂而高级的操作,例如:

●       区分(可以是标记或删除)字符串中所有重复的单词,例如,把The computer books books转换为The computer books。

●       把所有单词都转换为标题格式,例如把this is a Title转换为This Is A Title。

●       把长于3个字符的所有单词都转换为标题格式,例如把this is a Title转换为This is a Title。

●       确保句子有正确的大写形式。

●       区分URI的各个元素(例如http://www.wrox.com,提取出协议、计算机名、文件名等)。

本质上是实例化了一个对象System.Text.Regular Expressions.RegEx(甚至更简单:调用静态的RegEx()方法),给它传送要处理的字符串和一个正则表达式(这是一个字符串,包含用正则表达式语言编写的指令),就可以了。

正则表达式字符串初看起来像是一般的字符串,但其中包含了转义序列和有特定含义的其他字符。例如,序列\b表示一个字的开头和结尾(字的边界),如果要表示正在查找以字符th开头的字,就可以编写正则表达式\bth(即序列字边界是– t – h)。如果要搜索所有以th结尾的字,就可以编写th\b(序列t – h–字边界)。但是,正则表达式要比这复杂得多,包括可以在搜索操作中找到存储部分文本的工具性程序。本节仅介绍正则表达式的功能。

1.3.1 RegularExpressionsPlayaround示例

下面将开发一个小示例RegularExpressionsPlayaround,执行并显示一些搜索的结果,说明正则表达式的一些特性,以及如何在C#中使用.NET正则表达式引擎。

string Text =
@"This comprehensive compendium provides a broad and thorough investigation of all
aspects of programming with ASP.NET. Entirely revised and updated for the 3.5
Release of .NET, this book will give you the information you need to master ASP.NET
and build a dynamic, successful, enterprise Web application.";
string Pattern = "ion";

//这个方法的参数是一些输入文本、一个模式和RegexOptions枚举中的一组可选标志。
MatchCollection Matches = Regex.Matches(Text, Pattern,

                                    RegexOptions.IgnoreCase |

                                    RegexOptions.ExplicitCapture);

foreach (Match NextMatch in Matches)
{
   Console.WriteLine(NextMatch.Index);
}

为了说明正则表达式.NET类,我们先进行一次纯文本的搜索,这次搜索不带任何转义序列或正则表达式命令。在这段代码中,使用了System.Text.RegularExpressions命名空间中Regex类的静态方法Matches()。在本例中,指定所有的搜索都不应区分大小写。另一个标记ExplicitCapture 改变了收集匹配的方式,对于本例,这样可以使搜索的效率更高,其原因详见后面的内容(尽管它还有这里没有介绍的其他用法)。Matches()返回MatchCollections对象的引用。匹配是一个技术术语,表示在表达式中查找模式实例的结果,用System.Text.RegularExpressions.Match来代表。因此,我们返回一个包含所有匹配的MatchCollection,每个匹配都用一个Match对象来表示。在上面的代码中,只是在集合中迭代,使用Match类的Index属性,返回输入文本中匹配所在的索引。

下表描述了RegexOptions枚举的一些选项。

但正则表达式的功能主要取决于模式字符串。原因是模式字符串不仅仅包含纯文本。如前所述,它还可以包含元字符和转义序列,其中元字符是给出命令的特定字符,而转义序列的工作方式与C#的转义序列相同,它们都是以反斜杠\开头的字符,具有特殊的含义。

例如,假定要查找以n开头的字,就可以使用转义序列\b,它表示一个字的边界(字的边界是以字母数字表中的某个字符开头,或者后面是一个空白字符或标点符号)。可以编写如下代码:

string Pattern = @"\bn";

// string Pattern = @"ion\b"; 查找以序列ion结尾的字

// string Pattern = @"\bn\S*ion\b";查找以字母a开头,以序列ion结尾的所有字

MatchCollection Matches = Regex.Matches(Text, Pattern,

                                    RegexOptions.IgnoreCase |

                                    RegexOptions.ExplicitCapture);

注意字符串前面的符号@。要在运行时把\b传递给.NET正则表达式引擎,反斜杠\不应被C#编译器解释为转义序列。

下表是可以使用的一些主要的特定字符或转义序列,但这个表并不完整,完整的列表请参考MSDN文档。

如果要搜索一个元字符,也可以通过带有反斜杠的转义字符来表示。例如,.(一个句点)表示除了换行字符以外的任何字符,而\.表示一个点。

可以把替换的字符放在方括号中,请求匹配包含这些字符。例如,[1|c]表示字符可以是1或c。如果要搜索map或man,可以使用序列ma[n|p]。在方括号中,也可以指定一个范围,例如[a-z]表示所有的小写字母,[A-E]表示A到E之间的所有大写字母,[0-9]表示一个数字。如果要搜索一个整数(该序列只包含0到9的字符),就可以编写[0-9]+(注意,使用+字符表示至少要有这样一个数字,但可以有多个数字,所以9、 83和 854等都是匹配的)。

1.3.2  匹配、组合和捕获

正则表达式的一个很好的特性是可以把字符组合起来,其方式与C#中的复合语句一样。在C#中,可以把任意数量的语句放在花括号中,把它们组合在一起。其结果就像一个复合语句那样。在正则表达式模式中,也可以把任何字符组合起来(包括元字符和转义序列),像处理一个字符那样处理它们。唯一的区别是要使用圆括号,而不是花括号,得到的序列称为一个组。

例如,模式(an)+定位序列an的任意重复。量词+只应用于它前面的一个字符,但因为我们把字符组合起来了,所以它现在把重复的an作为一个单元来对待。(an)+应用到输入文本bananas came to Europe late in the annals of history上,会从bananas中选择出anan。另一方面,如果使用an+,则程序将从annals中选择ann,从bananas中选择出两个an。表达式(an)+可以提取出an、anan、ananan等,而表达式an+可以提取出an、ann、annn等。

但是,组的功能要比这强大得多。在默认情况下,把模式的一部分组合为一个组时,就要求正则表达式引擎按照这个组来匹配,或按照整个模式来匹配。换言之,可以把组当作一个要匹配的模式来返回,如果要把字符串分解为各个部分,这种模式就是非常有效的。

例如,URI的格式是<protocol>://<address>:<port>,其中端口是可选的。它的一个示例是http://www.wrox.com:4355。假定要从一个URI中提取协议、地址和端口,而且紧邻URI的后面可能有空白(但没有标点符号),就可以使用下面的表达式:


该表达式的工作方式如下:首先,前导b序列和结尾b序列确保只需要考虑完全是字的文本部分。在这个文本部分中,第一组https?)会识别http或htps协议。S字符后面的?指定这个字符可能出现0次或1次,因此找到http和htps。括号表示把协议存储为一组。

第二组是一个(://),它仅指定字符://

第三组([.\w]+)比较有趣。这个组包含一个放在括号里的表达式,该表达式要么是句点字符(.),要么是用\w指定的任意字母数字字符。这些字符可以重复任意多次,因此匹配www.wrox.com。

第四组([\s:]([\d]{2,5})?)是一个较长的表达式,包含一个内部组。在该组中,第一个放在括号中的表达式允许通过s指定空白字符或冒号。内部组用\d指定一个数字。表达式{2,5}指定前面的字符(数字)允许至少出现两次但不超过5次。数字的完整表达式用内部组后面的?指定允许出现0次或1次。使这个组变成可选非常重要,因为端口号并不总是在URI中指定;事实上,通常不指定它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/888210.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

‌图片编辑为底片,智能工具助力,创作精彩视觉作品

在当今数字化时代&#xff0c;图像编辑已成为表达创意和美化视觉作品的重要手段。借助智能工具&#xff0c;即使是初学者也能轻松驾驭图片编辑。接下为大家展示图片编辑为底片图片的效果。 1.打开“首助编辑高手”&#xff0c;选择这里“图片批量处理”版块页面上 2.导入保存有…

【AIGC产品经理】面试7家,拿到2个offer,薪资中上水平

Hello&#xff0c;大家好&#xff0c;我是一名不知名的5年B端金融产品经验的产品经理&#xff0c;成功转行AI产品经理&#xff0c;前期面试了北京百度、阿里、理想汽车、百川智能、华为、OPPO等多家大厂面试&#xff0c;但是由于已定居成都&#xff0c;主动终止了后续需要线下的…

uniapp 游戏 - 使用 uniapp 实现的扫雷游戏

0. 思路 1. 效果图 2. 游戏规则 扫雷的规则很简单。盘面上有许多方格,方格中随机分布着一些雷。你的目标是避开雷,打开其他所有格子。一个非雷格中的数字表示其相邻 8 格子中的雷数,你可以利用这个信息推导出安全格和雷的位置。你可以用右键在你认为是雷的地方插旗(称为标…

Web和UE5像素流送、通信教程

一、web端配置 首先打开Github地址&#xff1a;https://github.com/EpicGamesExt/PixelStreamingInfrastructure 找到自己虚幻引擎对应版本的项目并下载下来&#xff0c;我这里用的是5.3。 打开项目找到PixelStreamingInfrastructure-master > Frontend > implementat…

Docker系列-5种方案超详细讲解docker数据存储持久化(volume,bind mounts,NFS等)

文章目录 Docker的数据持久化是什么&#xff1f;1.数据卷&#xff08;Data Volumes&#xff09;使用Docker 创建数据卷创建数据卷创建一个容器&#xff0c;将数据卷挂载到容器中的 /data 目录。进入容器&#xff0c;查看数据卷内容停止并重新启动容器&#xff0c;数据卷中的数据…

Vue2电商项目(八) 完结撒花:图片懒加载、路由懒加载、打包的map文件

一、图片懒加载 安装&#xff1a;npm i vue-lazyload1.3 -s &#xff08;弹幕建议按1.3版本&#xff09; 引入 // 引入懒加载的图片 import hlw from /assets/hulu.jpg // 引入插件 import VueLazyload from vue-lazyload // 引入插件 Vue.use(VueLazyload, {// 懒加载默认的图…

【Linux-基础IO】磁盘的存储管理详解

磁盘的存储管理 由于一个磁盘中包含了大量的扇区&#xff0c;为了方便管理&#xff0c;我们对磁盘进行了分区&#xff0c;其中每个分区又进一步划分为多个块组&#xff08;Block Group&#xff09;&#xff0c;每个块组中包含该块组的数据存储情况以及具体的数据 假设有一个8…

前端练习小项目 —— 让图片变得更 “色”

前言&#xff1a;相信读者在学习完了HTML、CSS和JavaScript之后已经想要迫不及待的想找一个小型的项目来练练手&#xff0c;那么这篇文章就正好能满足你的 “需求”。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 在开始学习…

SpringBoot基础(三):Logback日志

SpringBoot基础系列文章 SpringBoot基础(一)&#xff1a;快速入门 SpringBoot基础(二)&#xff1a;配置文件详解 SpringBoot基础(三)&#xff1a;Logback日志 目录 一、日志依赖二、日志格式1、记录日志2、默认输出格式3、springboot默认日志配置 三、日志级别1、基础设置2、…

Linux中的网络指令:ping、netstat、watch、pidof、xargs

目录 Ping指令 netstat指令 watch指令 pidof指令 xargs指令 Ping指令 功能&#xff1a;检测两台主机间的网络连通性 语法&#xff1a;ping [选项] 目标主机的IP地址 &#xff08;192.168.1.1&#xff09;或域名&#xff08;google.com&#xff09; 常见选项&#xff1a…

P1010 [NOIP1998 普及组] 幂次方 Python题解

[NOIP1998 普及组] 幂次方 题目描述 任何一个正整数都可以用 2 2 2 的幂次方表示。例如 137 2 7 2 3 2 0 1372^7 2^3 2^0 137272320。 同时约定次方用括号来表示&#xff0c;即 a b a^b ab 可表示为 a ( b ) a(b) a(b)。 由此可知&#xff0c; 137 137 137 可表示…

华为 HCIP-Datacom H12-821 题库 (33)

&#x1f423;博客最下方微信公众号回复题库,领取题库和教学资源 &#x1f424;诚挚欢迎IT交流有兴趣的公众号回复交流群 &#x1f998;公众号会持续更新网络小知识&#x1f63c; 1.VLAN Pool 只要通过一个 SSID 就能够同时支持多个业务 VLAN&#xff0c;从而缩小广播域&#…

draw.io 设置默认字体及添加常用字体

需求描述 draw.io 是一个比较好的开源免费画图软件。但是其添加容器或者文本框时默认的字体是 Helvetica&#xff0c;一般的期刊、会议论文或者学位论文要求的英文字体是 Times New Roman&#xff0c;中文字体是 宋体&#xff0c;所以一般需要在文本字体选项里的下拉列表选择 …

Spring开发最佳实践之跨域处理

1. 跨域处理 1.1 异常现象 1.2 异常原因分析 跨源资源共享的官方定义如下&#xff1a; 跨源资源共享&#xff08;CORS&#xff0c;Cross Origin Resource Sharing。或通俗地译为跨域资源共享&#xff09;是一种基于 HTTP 头的机制&#xff0c;该机制通过允许服务器标示除了它自…

线性代数入门

线性代数入门 线性代数&#xff08;Linear Algebra&#xff09;是数学的重要分支之一&#xff0c;广泛应用于工程、计算机科学、物理学、经济学等领域。它主要研究向量、矩阵及其在空间中的变换。对于程序员来说&#xff0c;掌握线性代数的基础知识能够帮助更好地理解数据处理…

[C++]使用纯opencv部署yolov8-cls图像分类onnx模型

【算法介绍】 使用纯OpenCV部署YOLOv8-cls图像分类ONNX模型涉及几个关键步骤。 首先&#xff0c;你需要将YOLOv8-cls模型从PyTorch格式转换为ONNX格式&#xff0c;这是为了确保模型在不同深度学习框架之间的互操作性。这个转换过程通常是通过ultralytics框架中的model.export…

Linux TFTP服务器搭建

话得多说 先水一波字 TFTP&#xff08;Trivial File Transfer Protocol&#xff09;是一种简单的文件传输协议。它用于在计算机网络中传输文件&#xff0c;特别适用于在网络设备&#xff08;如开发板和Linux系统下&#xff09;代码调试等操作。TFTP使用UDP&#xff08;User Da…

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz

SpringBoot教程&#xff08;二十四&#xff09; | SpringBoot实现分布式定时任务之Quartz 简介适用场景Quartz核心概念Quartz 存储方式Quartz 版本类型引入相关依赖开始集成方式一&#xff1a;内存方式(MEMORY)存储实现定时任务1. 定义任务类2. 定义任务描述及创建任务触发器3.…

C语言的柔性数组

目录 柔性数组1.柔性数组的特点&#xff1a;2.柔性数组的使用3.柔性数组的优势 柔性数组 也许你从来没有听说过柔性数组&#xff08;flexible array&#xff09;这个概念&#xff0c;但是它确实是存在的。 C99 中&#xff0c;结构体中的最后⼀个元素允许是未知⼤⼩的数组&…

程序员日志之DNF手游女鬼剑异界套选择思路

目录 传送门正文日志1、概要2、剑宗3、剑豪4、剑魔5、暗帝 传送门 SpringMVC的源码解析&#xff08;精品&#xff09; Spring6的源码解析&#xff08;精品&#xff09; SpringBoot3框架&#xff08;精品&#xff09; MyBatis框架&#xff08;精品&#xff09; MyBatis-Plus Sp…