56从零开始学Java之与字符串相关的正则表达式
作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦
千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者
前言
在上一篇文章中,壹哥给大家介绍了String字符串及其各种常用API方法,接下来壹哥继续给大家讲解一些String字符串的高级玩法。
有时候我们操作一个字符串时,这个字符串的内容并不一定就是固定不变的。比如在用户注册时,我们要求用户在输入框中输入自己的手机号码。我们知道,每个人的手机号码都是不一样的,那我们该如何保证用户输入的是合法的手机号呢?这就需要我们在代码中对这个手机号进行验证审核,不能随便输入11位数字就行了。这时,就需要对用户传递过来的字符串参数进行校验。
作为一个程序员,你可能会想到通过一段代码程序来进行判断,但这种方法需要创建对应的判断规则,然后用一堆的代码进行实现,比如:
boolean isValidMobileNumber(String s) {// 是否是11位?if (s.length() != 11) {return false;}// 每一位都是0~9:for (int i=0; i<s.length(); i++) {char c = s.charAt(i);if (c < '0' || c > '9') {return false;}}return true;
}
但上面的代码只是做了非常粗略的判断,并未考虑首位数字不能为0等更详细的情况,而且以后随着发展,可能手机号不只有11位,或者会有其他的规则。那时候再修改代码吗?这就很麻烦!
实际上,在开发时,如果我们想实现该功能,比较普遍且靠谱的做法,是利用正则表达式来进行实现。那么什么是正则表达式?它有哪些特点?怎么用?接下来就请大家跟随壹哥来学习今天的内容吧。
----------------------------------------------前戏已做完,精彩即开始--------------------------------------------
全文大约【6000】字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......
配套开源项目资料
Github:
https://github.com/SunLtd/LearnJava
Gitee:
一一哥/从零开始学Java
一. 正则表达式
1. 简介
有挺多小伙伴之前听说过正则表达式,觉得这是一个很牛逼、很神奇的知识点,所以隐隐地觉得正则表达式学起来也会比较难。实际上,正则表达式的学习并不难!它其实是一种非常实用且简单的字符串操作工具,主要是作为匹配字符串的模板,能够将某个字符模式与所搜索的字符串进行对比匹配,并且正则表达式只是一套标准规范,和具体的某种开发语言并没有关系。也就是说,正则表达式不是java、python等某个语言独有的,而是在各种语言中都通用的,只是在每种语言中可能会有个别细微的差别。
而在正式开始学习正则表达式之前,让我们先来了解一下正则表达式的概念:
正则表达式是由各种普通的字符(如a~z、A~Z、0~9),以及一些特殊字符(元字符)组成的文字模板,是一种用于模式匹配和替换的规范。通俗地说,我们可以把正则表达式理解成是一种可以对字符串进行各种特殊处理的工具,比如可以对字符串进行【查找、提取、分割、替换】等操作。
也即是说,正则表达式只是一个描述规则的字符串。所以,只需要编写出正确的规则,我们就可以让正则表达式去判断目标字符串是否符合规则。比如"Hello World"这样的字符串也是一个正则表达式,它可以匹配 "Hello World"这个字符串。一个【点号】也是一个正则表达式,它可以匹配任意一个字符,如"a" 、"A"、"1"等。
2. 基本语法
知道了正则表达式的基本概念之后,接下来我们还需要了解它的一些基本语法及其含义。以下是开发时常用的正则表达式基本语法,各种复杂的正则表达式其实都是由这些基本的语法规则组成的。大家要注意,正则表达式的匹配规则都是按照从左到右进行匹配的,并且通过不同的符号组合,可以实现对字符串的精确匹配、模糊匹配,也可以匹配字母、数字、各种符号等。
| 字符 | 说明 |
| () | 标记子表达式的开始和结束位置。要匹配这些字符,请使用\(和\) |
| [] | 用于确定中括号表达式的开始和结束位置。要匹配这些字符,请使用\[和\] |
| {} | 用于标记前面子表达式的出现频度。要匹配这些字符,请使用\{和\} |
| \ | 代表转义字符,将下个一字符标记为特殊字符、文本、反向引用或八进制转义符。例如, n匹配字符 n,\n 匹配换行符,序列 \\\\ 匹配 \\ ,\\( 匹配 (。 |
| | | 指定两项之间任选一项。如果要匹配丨字符本身,请使用\| |
| ^ | 表示否定,例如[^abc]表示非 a、b、c 的任意字符;[^a-f]表示不是 a~f 范围内的任意字符 |
| $ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与"\n"或"\r"之前的位置匹配。 |
| * | 表示零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo",* 等同于 {0,}。 |
| + | 表示一次或多次匹配前面的字符或子表达式。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。 |
| ? | 表示零次或一次匹配前面的字符或子表达式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效于 {0,1}。 |
| &&,“与”运算: | 例如 [a-z&&[def]],是 a~z 和 [def] 的交集,表示 d、e; |
| “并”运算 | 并运算与前面的枚举类似,例如[a-d[m-p]]表示 [a-dm-p] |
| {n} | n 是非负整数,表示正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。 |
| {n,} | n 是非负整数,表示至少匹配 n 次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有 o。"o{1,}"等效于"o+"。"o{0,}"等效于"o*"。 |
| {n,m} | m 和 n 是非负整数,其中 n <= m,表示匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的头三个 o。'o{0,1}' 等效于 'o?'。注意,逗号和数字之间不能有空格。 |
| ? | 当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式表示匹配搜索到尽可能短的字符串,而默认"贪心的"模式则会匹配搜索到尽可能长的字符串。例如,在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。 |
| . | 代表除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。 |
| (pattern) | 代表pattern,并捕获与之匹配的子表达式。可以使用 $0…$9 属性,从"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"\("或者"\)"。 |
| (?:pattern) | 代表pattern,但不捕获与之匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对用"or"字符 (|) 组合模式部件的情况很有用,例如,'industr(?:y|ies) 是比 'industry|industries' 更经济的表达式。 |
| (?=pattern) | 执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 |
| (?!pattern) | 执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 |
| x|y | 代表 x 或 y。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。 |
| X | 字符x(x代表任何合法的字符) |
| [xyz] | 字符集。匹配包含的任一指定字符。例如,"[abc]"匹配"plain"中的"a"。 |
| [^xyz] | 代表反向字符集。匹配未包含在指定字符集的任何字符。例如,"[^abc]"可以匹配"plain"中"p","l","i","n"。 |
| [a-z] | 枚举字符范围,匹配指定范围内的任何字符。例如"[a-z]",用于匹配"a"到"z"范围内的任何小写字母。 |
| [^a-z] | 反向范围字符,匹配不在指定范围内的任何字符。例如,"[^a-z]"匹配所有不在"a"到"z"范围内的任何字符。 |
| \b | 匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。 |
| \B | 代表非字边界。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。 |
| \cx | 匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是"c"字符本身。 |
| \d | d即digit,代表数字字符,等效于 [0-9]。 |
| \D | 代表非数字字符,等效于 [^0-9]。 |
| \f | 代表换页符,等效于 \x0c 和 \cL。 |
| \n | 代表换行符,等效于 \x0a 和 \cJ。 |
| \r | 代表一个回车符,等效于 \x0d 和 \cM。 |
| \s | s即space,代表任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。 |
| \S | 代表任何非空白字符,与 [^ \f\n\r\t\v] 等效。 |
| \t | 代表制表符,与 \x09 和 \cI 等效。 |
| \v | 代表垂直制表符,与 \x0b 和 \cK 等效。 |
| \w | w即word,代表任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。 |
| \W | 代表任何非单词字符,与"[^A-Za-z0-9_]"等效。 |
| \xn | 代表n,此处的 n 是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,"\x41"匹配"A"。"\x041"与"\x04"&"1"等效。允许在正则表达式中使用 ASCII 代码。 |
| \num | 代表num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,"(.)\1"匹配两个连续的相同字符。 |
| \n | 标识一个八进制转义码或反向引用。如果 \n 前面至少有 n 个捕获子表达式,那么 n 是反向引用。否则,如果 n 是八进制数 (0-7),那么 n 是八进制转义码。 |
| \nm | 标识一个八进制转义码或反向引用。如果 \nm 前面至少有 nm 个捕获子表达式,那么 nm 是反向引用。如果 \nm 前面至少有 n 个捕获,则 n 是反向引用,后面跟有字符 m。如果两种前面的情况都不存在,则 \nm 匹配八进制值 nm,其中 n 和 m 是八进制数字 (0-7)。 |
| \nml | 当 n 是八进制数 (0-3),m 和 l 是八进制数 (0-7) 时,匹配八进制转义码 nml。 |
| \un | 代表n,其中 n 是以四位十六进制数表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (©)。 |
有的小伙伴会说,上面这么多的规则,我记不住啊!其实大家不用担心,我们没必要把以上这些规则都记住,只需记住几个常用的语法规则,以后开发时如果需要编写正则表达式,随时查阅API就可以了。而且现在网上也有很多第三方的正则表达式编写网站,很多常用的表达式都已经写好了,我们只需要将这些规则直接拿来用即可。但是我们需要知道基本的规则,这样当有特殊需要时才能灵活修改组合,满足我们的特殊需求。
当然,我们在开发时编写的正则表达式,并不会像上表中展示的那样简单,可能是很复杂。但不管如何,这些复杂的表达式,都是由这些基本的语法规则组成的,我们了解这些基本规则即可。
3. 常用API
3.1 String中的正则表达式操作方法
为了让我们方便操作正则表达式,String类给我们提供了如下几个API方法,可以让我们结合正则表达式对字符串进行各种操作:
- boolean matches(String regex):判断该字符串是否匹配了指定的正则表达式;
- String replaceAll(String regex, String replacement):将该字符串中所有匹配了regex规则的子串都替换成replacement;
- String replaceFirst(String regex, String replacement):将该字符串中第一个匹配regex规则的子串替换成replacement;
- String[] split(String regex):以regex作为分隔符,把该字符串分割成多个子串。
以上API方法的使用格式如下所示:
//正则表达式
String reg = "a*c";
//对某个字符串进行匹配判断
boolean result="abc".matches(reg);//利用正则表达式对字符串进行替换,把用不规范的连续空格分隔的句子变成规范的句子
String s = "The fast\t\t snow down on the land cat.";
String r = s.replaceAll("\\s+", " ");
3.2 正则表达式相关的操作类
上面这些方法都是Java提供的用于操作正则表达式的API方法,另外在java.util.regex包中也提供了以下三个可以操作正则表达式的类:
- Pattern类:Pattern对象是正则表达式编译后在内存中的表示形式,因此正则表达式字符串必须先被编译为 Pattern对象,然后再利用该 Pattern对象创建对应的Matcher对象。执行匹配所涉及的状态保留在Matcher对象中,多个Matcher对象可共享同一个Pattern对象。Pattern类没有公共的构造方法。如果我们想要创建Pattern对象,可以调用其公共的静态方法compile(),它会返回一个Pattern对象,且该方法要接受一个正则表达式作为它的第一个参数。
- Matcher类:Matcher类是对输入的字符串进行解释和匹配操作的引擎,该类也没有公共的构造方法,我们可以通过Pattern对象的matcher()方法来获得一个Matcher对象。
- PatternSyntaxException类:PatternSyntaxException是一个非强制的异常类,它可以表示在正则表达式中出现的语法异常。
以上API类的使用格式如下所示:
//将一个正则表达式字符串编译成Pattern对象
Pattern p = Pattern.compile("某个正则表达式,如a*b");//使用Pattern对象创建Matcher对象,匹配某个字符串
Matcher m = p.matcher("abbbb");//返回匹配结果,此处会返回true
boolean b = m.matches();
二. 基本使用
了解了以上这些基础内容之后,接下来壹哥再通过几个实际案例,来带大家综合运用一下上面的内容。
1. 验证电话号码
我们在访问网站或APP时,经常会需要我们通过手机号来注册个会员,这时就需要我们输入电话号码。这个电话号码包括手机号码或者固定电话两种情况,两者的格式有点不同。但不管怎么样,网站或APP都会验证用户输入的电话号码是否合法,否则就会给用户一些提示。接下来壹哥就给大家设计一个验证电话号码是否合法的案例,通过本案例来综合练习一下前面学习过的内容。
1.1 正则表达式
壹哥直接给大家贴出了如下正则表达式,该正则表达式就可以用于验证电话号码是否合法。
String regex = "0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|18[0-9]\\d{8}|15[1234]\\d{8}";
接下来壹哥再给大家解释一下该表达式的含义。
1.1.1 匹配固定电话
- 首先电话号码包括固定电话和手机号码,其中固定电话由区号和号码组成,手机号目前是11位纯数字;
- 固话的区号部分,以 0 开头,后面是 2~3 位数,因此在匹配区号时可以使用0\d{2,3}这个正则表达式;
- 固话的号码部分由 7~8 位数字组成,因此可以使用\d{7,8}表达式来进行匹配;
- 又因为固定电话的组合方式可能是“区号-号码” 或 “区号号码”,因此匹配固定电话号码时,可以使用“0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}”表达式。
1.1.2 匹配手机号码
- 手机号码是11位纯数字,一般以数字“1x”开头,但不同运营商的手机号开头并不相同。
- 考虑到手机号码的特殊性,本案例只给大家示范18xxxxxxxxx和15xxxxxxxxx号段的手机号,我们可以使用“18[0-9]\\d{8}|15[1234]\\d{8}”这个表达式进行匹配。
- 该正则表达式会验证以18或15开头的手机号码,且15开头的手机号码,第3位数字只能是1、2、3、4中的一个。
1.2 代码实现
分析完了电话号码的正则表达式,我们再看看如何在Java代码中进行实现。
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/**
* @author 一一哥Sun
*/
public class Demo11 {public static void main(String[] args) {//定义一个用于匹配电话号码的正则表达式String regex = "0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}|18[0-9]\\d{8}|15[1234]\\d{8}";//定义一个结束循环的标志位String flag = "Y";do {System.out.print("请输入电话号码:");// 接收用户在控制台输入的电话号码Scanner scan = new Scanner(System.in);String phone = scan.next(); // 编译正则表达式Pattern pattern = Pattern.compile(regex); // 创建给定输入模式的匹配器Matcher matcher = pattern.matcher(phone); //进行字符串的匹配boolean bool = matcher.matches();if(bool) { // 如果验证通过System.out.println("电话号码格式可用");} else {System.out.println("电话号码不可用,请重新输入!");}System.out.print("是否继续注册?(请输入 Y/N 或 y/n)");flag=scan.next();}while(flag.equalsIgnoreCase("Y"));System.out.println("注册结束!");}
}
在本案例中,我们使用 do…while 语句进行循环判断,接收用户在控制台输入的电话号码,接着通过Pattern类进行编译,创建给定输入模式的匹配器,调用 matches()方法返回匹配的结果。如果结果为true,则表示验证通过;如果为false,则表示验证失败。最后再通过输入Y或N来判断是否结束循环。
2. 验证身份证号
2.1 身份证规则简介
我们知道,目前国内的二代身份证一般都是18位的,但因为历史遗留原因,还有个别一代身份证号码可能是15位的。一般18位或15位的身份证号码格式如下:
- 十八位号码:xxxxxx yyyy MM dd 375 0
- 十五位号码:xxxxxx yy MM dd 75 0
其中,身份证包含地区、日期、特殊字符来组成,一般的组成规则如下:
- 地区是6位的纯数字:[1-9][0-9]{5};
- 年份的前两位目前只能是18、19、20:(18|19|20) ,表示18-20;
- 年份的后两位可以是0-9之间的数字: [0-9]{2} 即00-99;
- 月份只有12个:((0[1-9])|(10|11|12)) ,即01-12;
- 天数,最多到31:(([0-2][1-9])|10|20|30|31) ,即1-31,这里无法对二月份特殊处理;
- 18位身份证后三位的顺序码:[0-9]{3},即000-999;
- 15位身份证后两位的顺序码:[0-9]{2},即00-99;
- 最后的校验码:15位身份证号的是[0-9] ,18位身份证号的则是([0-9]|(X|x)),只有18位的才会出现Xx。
2.2 正则表达式
根据上面的规则分析,我们就可以设计出身份证号码对应的正则表达式。
//18位号码
String id_18="^[1-9][0-9]{5}(18|19|20)[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{3}([0-9]|(X|x))";//15位号码
String id_15="^[1-9][0-9]{5}[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{2}[0-9]";
2.3 代码实现
接下来我们就在Java代码中,对身份证号进行验证,看看是否合法。
public class Demo13 {public static void main(String[] args) {//18位号码的正则表达式String reg18 = "^[1-9][0-9]{5}(18|19|20)[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{3}([0-9]|(X|x))";//15位号码的正则表达式String reg15 = "^[1-9][0-9]{5}[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{2}[0-9]";//编译正则表达式String validStr = "(" + reg18 + ")" + "|" + "(" + reg15 + ")";Pattern pattern = Pattern.compile(validStr);//匹配身份证号是否合法,请在这里传入自己18/15位的身份证号Matcher matcher = pattern.matcher("140826198812190122");System.out.println("身份证号是否合法:"+matcher.matches());}}
-----------------------------------------------正片已结束,来根事后烟---------------------------------------------
三. 结语
至此,壹哥就把正则表达式给大家简单地介绍完了,今天的重点内容如下:
- 掌握正则表达式的基本语法规则;
- 掌握Java代码中使用正则表达式;
- 了解几个常用的正则表达式匹配规则,比如手机号、身份证号等的验证;
另外如果你独自学习觉得有很多困难,可以加入壹哥的学习互助群,大家一起交流学习。
四. 今日作业
作业1:
在正则表达式中,*、+、?三个符号有什么区别?请在评论区说出你的答案。
作业2:
请设计一个正则表达式,验证一个电子邮箱格式是否合法。
相关文章:
56从零开始学Java之与字符串相关的正则表达式
作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在上一篇文章中,壹哥给大家介绍了String字符串及其各种常用API方法,接下来壹哥…...
STM32 定时器自动重装载寄存器ARR带来的影响,ARPE0和1区别
ARR是啥 自动重载寄存器是预装载的。对自动重载寄存器执行写入或读取操作时会访问预装载寄存器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 (UEV) 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 …...
vue 把<style scoped lang=“less“> 单独写成less文件再导入使用
1 npm npm install less-loader --save-dev2 创建一个单独的 Less 文件,例如 app.less <style scoped lang"less"> import url(./app.less); </style>3 在 app.less 文件中,编写 Less 样式代码 .container {width: 500px;margi…...
C++ 字符串
C 字符串 一、字符串两种写法 c语言的写法,可以延用 const char* str1 "huang"; char str2[] "Hello, World!";c写法 std::string str "Hello, World!";二、字符串计算长度 c语言的计算字符串长度,需要导入库 #inc…...
springboot 报错处理(长期更新 2023.8.10)
目录 一、HTTP 相关1.1、 数据传输方面1.1.1、 HttpMessageNotWritableException1.1.1.1、 springboot + stomp 场景一、HTTP 相关 1.1、 数据传输方面 1.1.1、 HttpMessageNotWritableException 1.1.1.1、 springboot + stomp 场景 报错内容: 使用 spring boot 和 stomp 服…...
Maven出现报错 ; Unable to import maven project: See logs for details错误的多种解决方法
问题现象; IDEA版本: Maven 版本 : 3.3.9 0.检查 maven 的设置 :F:\softeware\maven\apache-maven-3.9.3\conf 检查setting.xml 配置 本地仓库<localRepository>F:\softeware\maven\local\repository</localRepository>镜像…...
33_windows环境debug Nginx 源码-安装WSL
文章目录 前言安装 WSL先决条件启用 windows 更新功能真正安装 WSL133_windows环境debug Nginx 源码-安装WSL前言 虽然很想在纯 windows 环境,基于windows 的生态完成debug,但现实情况是 由于Nginx 源码编写的很多内容都和 linux 更加耦合;且不说使用 Visual-Studio 安装 C/…...
Java中的ZooKeeper是什么?
Java中的ZooKeeper是一个开源的分布式协调服务,它可以帮助我们管理分布式系统中的数据和配置信息。ZooKeeper是由Facebook开发的一个开源项目,它被广泛用于Facebook的分布式系统。 ZooKeeper的名称来源于动物园管理员(Zookeeper)…...
【数学】CF1796 C
Problem - 1796C - Codeforces 题意: 思路: 模拟一下样例可以发现一些规律 Code: #include <bits/stdc.h>#define int long longusing i64 long long;constexpr int N 1e6 10; constexpr int mod 998244353;void solve() {int l…...
SCI论文中字体和图片字体大小的要求
SCI论文中字体和图片字体大小的要求 文章目录 1. American Chemical Society(ACS)要求2. Nature要求 1. American Chemical Society(ACS)要求 https://www.zhihu.com/question/380612293?utm_id0 2. Nature要求...
react-dnd的使用
介绍: React DnD(Drag and Drop)是一个用于实现拖放功能的 React 拓展库。它提供了一组用于构建可拖动和可放置组件的高阶组件和钩子函数。 使用: 安装 react-dnd 和 react-dnd-html5-backend: npm install react-d…...
ELF program/section segment解析
ELF program/section segment解析 1 elf program segment1.1 elf program header1.2 ELF32和ELF64示例1.2.1 ELF32 program segment1.2.2 ELF64 program segment 1.3 elf program segment数据流向图 2 elf section2.1 eld section header2.2 ELF32和ELF64示例2.2.1 ELF32 secti…...
【golang】库源码文件
库源码文件是不能被直接运行的源码文件,它仅用于存放程序实体,这些程序实体可以被其他代码使用(只要遵从Go语言规范的话)。 这里的“其他代码”可以与被使用的程序实体在同一个源码文件内,也可以在其他源码文件&#x…...
网络安全(黑客)常用工具(附配套资料+工具安装包)
几十年来,攻击方、白帽和安全从业者的工具不断演进,成为网络安全长河中最具技术特色的灯塔,并在一定程度上左右着网络安全产业发展和演进的方向,成为不可或缺的关键要素之一。 话不多说,2022年全球白帽常用工具排行榜…...
WebDAV之π-Disk派盘+Joplin
Joplin是一个优秀的开源笔记,可以组织到笔记本中的大量笔记和文本编辑器中进行复制,标记和修改。支持Evernote的笔记直接导入到Joplin应用程序中。Joplin还支持各种云服务同步,包括Dropbox、OneDrive、WebDAV或文件系统,方便对其进行检查、备份和移动。该应用程序可用于Win…...
Unity-UGUI优化策略
界面出栈规则: 界面目录导航、策划界面回退需求造成界面套娃问题,夹带一系列层级问题,应该和策划进行友好沟通,避免界面不合理的出栈入栈规则 overdraw: 尽量减少同屏 半透明物体渲染 Unity 之 UGUI优化(…...
【练】Linux中用共用体(联合体)的方式,判断本机的字节序
方法一:共用体 #include <stdio.h> union Byte {unsigned int a;char c; }; int main(int argc, const char *argv[]) {union Byte endianness;endianness.a0x87654321;printf("endianness.c%#x\n",endianness.c); if(0x21 endianness.c)pr…...
WebRTC | 音视频直播客户端框架
端到端通信互动技术可分解为以下几个技术难点:客户端技术、服务器技术、全球设备网络适配技术和通信互动质量监控与展示技术。 一、音视频直播 音视频直播可分成两条技术路线:一条是以音视频会议为代表的实时互动直播;另一条是以娱乐直播为代…...
flutter开发实战-实现marquee根据文本长度显示文本跑马灯效果
flutter开发实战-实现marquee文本跑马灯效果 最近开发过程中需要marquee文本跑马灯效果,这里使用到了flutter的插件marquee 效果图如下 一、marquee 1.1 引入marquee 在pubspec.yaml中引入marquee # 跑马灯效果marquee: ^2.2.31.2 marquee使用 marquee使用也是…...
8.10论文阅读
文章目录 The multimodal MRI brain tumor segmentation based on AD-Net摘要本文方法损失函数 实验结果 max-vit - unet:多轴注意力医学图像分割摘要本文方法实验结果 The multimodal MRI brain tumor segmentation based on AD-Net 摘要 基于磁共振成像(MRI)的多模态胶质瘤…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...
