当前位置:网站首页>正则表达式的理解学习
正则表达式的理解学习
2022-08-02 06:14:00 【爱学习的大雄】
文章目录
基本介绍
一个正则表达式,就是用某种模式去匹配字符串的一个公式,很多人因为他们看上去比较古怪而且复杂所以不敢去使用,不过,经过练习后,就觉得这些复杂的表达式写起来还是相当简单的,而且,一旦你弄懂他们,你就能把数小时辛苦而且易错的文本处理工作缩短在几分钟(甚至几秒钟)内完成
这里要特别强调,正则表达式不是只有java才有,实际上很多编程语言都支持正则表达式进行字符串操作!比如:javascript,php,java…
代码示例:(带你了解正则表达式)
public class Regexp_ {
public static void main(String[] args) {
String str = "1998年12月8日,第二代Java平台的企业版J2EE发布。" +
"1999年6月,Sun公司发布了第二代Java平台(简称为Java2)" +
"的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版)" +
",应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard " +
"Edition,Java 2平台的标准版),应用于桌面环境;J2EE(" +
"Java 2Enterprise Edition,Java 2平台的企业版)," +
"应用于基于Java的应用服务器。Java 2平台的发布,是Java发展" +
"过程中最重要的一个里程碑,标志着Java的应用开始普及。";
//提取文中的所有英文单词
//(1)传统方式:采用遍历方式,代码量大,效率不高
//(2)正则表达式技术
//1.先创建一个Pattern对象,模式对象,可以理解成为就是一个正则表达式对象
//Pattern pattern = Pattern.compile("[a-zA-Z]+");
//数字
//Pattern pattern = Pattern.compile("[0-9]+");
//数字和英文单词
Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-Z]+)");
//2.创建一个匹配器对象
//理解: matcher 匹配器按照 pattern(模式/样式),到str中去匹配
//找到返回true,否则就返回false
Matcher matcher = pattern.matcher(str);
//3.可以开始循环匹配
while (matcher.find()){
//匹配内容,文本,放到 matcher.group(0) 中
System.out.println("找到:"+matcher.group(0));
}
}
}
正则表达式底层实现
为让大家对正则表达式底层实现有一个直观的映像,给大家举个实例
给你一段字段串(文本),请找出所有四个数字连在一起的子串,比如:应该找到 1998 1999 3443 9889 ===> 分析底层实现
public class RegTheory {
public static void main(String[] args) {
String str = "1998年12月8日,第二代Java平台的企业版J2EE发布。" +
"1999年6月,Sun公司发布了第二代Java平台(简称为Java2)" +
"的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版)" +
",应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard " +
"Edition,Java 2平台的标准版),应用于桌面环境;J2EE(" +
"Java 2Enterprise Edition,Java 2平台的企业版)," +
"应用于基于Java的应用服务器3443。Java 2平台的发布,是Java发展" +
"过程中最重要的一个里程碑,标志着Java的应用开始普及9889。";
//说明
//1. \\d 表示一个任意的数字(0-9)
String regStr = "\\d\\d\\d\\d";
//2.创建模式对象[即正则表达式对象]
Pattern pattern = Pattern.compile(regStr);
//3.创建匹配器
//说明 :创建匹配器 matcher ,按照正则表达式的规则,去匹配 str字符串
Matcher matcher = pattern.matcher(str);
//开始匹配
/* * matcher.find() 完成的任务 1. 根据指定的规则,定位满足规则的子字符串(比如1999) 2. 找到后,将 子字符串的**开始的索引**记录到 matcher 对象的属性 int[] groups; groups[0]=0(groups[0]的值会改变,每一个符合规则的子字符串开始的索引) 把该子字符串的结束的 **索引+1**的索引值 记录到groups[1] * (groups[1]的值会改变,每一个符合规则的子字符串结束的索引+1)=4 3. 同时记录oldLast 的值为 子字符串的结束的 索引+1 的索引值 , 即4。即下次执行find()方法时,就从35开始匹配 * * *matcher.group(0) 完成的任务 public String group(int group) { if (first < 0) throw new IllegalStateException("No match found"); if (group < 0 || group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) return null; return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString(); } 1. 根据groups[0]=0 和 groups[1]=4 的记录的位置, *从content 开始截取子字符串返回的值 就是 [0,4) 左闭右开, *即包含 0 但是不包含 4 2. 如果再次执行find方法,仍然按照上面分析来执行 * */
while (matcher.find()){
System.out.println(matcher.group(0));
}
}
}
什么是分组:正则表达式中有 小括号() 就表示分组,比如:(\d\d)(\d\d) ,第一个()就表示第1组,第二个()就表示第2组…以此类推,
那么分组后的底层又是怎么样的呢
public class RegTheory {
public static void main(String[] args) {
String str = "1998年12月8日,第二代Java平台的企业版J2EE发布。" +
"1999年6月,Sun公司发布了第二代Java平台(简称为Java2)" +
"的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版)" +
",应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard " +
"Edition,Java 2平台的标准版),应用于桌面环境;J2EE(" +
"Java 2Enterprise Edition,Java 2平台的企业版)," +
"应用于基于Java的应用服务器3443。Java 2平台的发布,是Java发展" +
"过程中最重要的一个里程碑,标志着Java的应用开始普及9889。";
//说明
//1. \\d 表示一个任意的数字(0-9)
String regStr = "(\\d\\d)(\\d\\d)";
//2.创建模式对象[即正则表达式对象]
Pattern pattern = Pattern.compile(regStr);
//3.创建匹配器
//说明 :创建匹配器 matcher ,按照正则表达式的规则,去匹配 str字符串
Matcher matcher = pattern.matcher(str);
//开始匹配
/* * matcher.find() 完成的任务 1. 根据指定的规则,定位满足规则的子字符串(比如1999) 2. 找到后,将 子字符串的**开始的索引**记录到 matcher 对象的属性 int[] groups; groups[0]=0(groups[0]的值会改变,每一个符合规则的子字符串开始的索引) 把该子字符串的结束的 **索引+1**的索引值 记录到groups[1] (groups[1]的值会改变,每一个符合规则的子字符串结束的索引+1)=4 也就是说:groups[0]和groups[1]的值,还是按照原来的规则赋值 但是,由于这里有了分组,需要记录 每个分组后子字符串的值 groups[2]:记录第一个分组,子字符串开始的索引值 =0 groups[3]:记录第一个分组,子字符串结束的索引+1 的值 =2 groups[4]:记录第二个分组,子字符串开始的索引值 =2 groups[5]:记录第二个分组,子字符串结束的索引+1 的值 =4 ...以此类推 3. 同时记录oldLast 的值为 子字符串的结束的 索引+1 的索引值 , 即4。即下次执行find()方法时,就从35开始匹配 * * *matcher.group(0) 完成的任务 public String group(int group) { if (first < 0) throw new IllegalStateException("No match found"); if (group < 0 || group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) return null; return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString(); } 1. 根据groups[0]=0 和 groups[1]=4 的记录的位置, *从content 开始截取子字符串返回的值 就是 [0,4) 左闭右开, *即包含 0 但是不包含 4 2. 如果再次执行find方法,仍然按照上面分析来执行 * */
while (matcher.find()){
//如果正则表达式有(),即分组
//取出匹配的规则如下
//但是不能 取 没有的分组
System.out.println(matcher.group(0));//输入 0 表示输出整个字符串
System.out.println("该字符串第一组的值:"+matcher.group(1));//输入 1 表示输出该字符串中的第一组
System.out.println("该字符串第二组的值:"+matcher.group(2));//输入 2 表示输出该字符串中的第二组
//...以此类推
}
}
}
正则表达式语法
如果想要灵活的运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:
- 限定符
- 选择匹配符
- 分组组合和反向引用符
- 特殊字符
- 字符匹配符
- 定位符
元字符-转义号 \
\符号 说明:在我们使用正则表达式取检索某些特殊字符的时候,需要用到转义符号,否则检索不到结果,甚至会报错的,案例:用 $ 去匹配 “abc$(” 会怎么样?
用 ( 去匹配 “abc$(” 会怎么样?
提示:在java的正则表达式中,两个\代表其它语言中的\
常见的需要用到转移符号的字符有以下几种:. * + ( ) $ / \ ? [ ] ^ { }
单独一个 . 点 不加转义符,匹配的是所有字符
public class RegExp01 {
public static void main(String[] args) {
String content = "abc$(abc(123(";
//String str = "$";没有匹配到结果
//String str = "(";//直接报错
//String str = "\\$";
String str = "\\(";
Pattern pattern = Pattern.compile(str);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println(matcher.group(0));
}
}
}
元字符-字符匹配符
符号 | 符号 | 示例 | 解释 |
---|---|---|---|
[] | 可接受的字符列表 | [efgh] | e、f、g、h中的任意一个字符 |
[^] | 不接受的字符列表 | [^abc] | 除abc之外的任意一个字符,包括数字和特殊符号 |
- | 连字符 | A-Z | 任意单个大写字母 |
表格中有一些 括号 不完整,是因为这个软件所导致
符号 | 含义 | 示例 | 说明 | 匹配输入 |
---|---|---|---|---|
. | 匹配除\n以外的任何字符,使用时,需要\. | a…b | 以a开头,b结尾,中间包括2个任意字符的长度为4的字符串 | aaab,aegb,a78b,a#*b |
\\d | 匹配单个数字字符,相当于[0-9] | \\d{3}(\\d)? | 包含3个或4个数字的字符串 | 123,9876 |
\\D | 匹配单个非数字字符,相当于[^0-9 | \\D(\\d)* | 以单个非数字字符开头,后接任意个数字字符串 | a,A342 |
\\w | 匹配单个数字、大小写字母和下划线字符,相当于[0-9a-zA-Z_ | \\d{3}\\w{4} | 以3个数字字符开头的长度为7的数字字母字符串 | 234abcd,12354jk |
\\W | 匹配单个非数字,大小写字母字符,相当于[^0-9a-zA-Z_ | \\W+\\d{2} | 以至少1个非数字开头字母字符开头,2个数字字符结尾的字符串 | #29,#[email protected] |
\\s | 匹配任何空白字符(空格,制表符等) | \\s | ljk kjk | |
\\S | 匹配任何非空白字符和\s刚好相反 | \\S | jkjklj ghjj |
java正则表达式默认是区分字母大小写的,如何实现不区分大小写
- (?i)abc:表示abc都不区分大小写
- a(?i)bc:表示bc不区分大小写
- a((?i)b)c:表示只有b不区分大小写
- Pattern pat = Pattren.compile(regEX,Pattern.CASE_INSENSITIVE);
元字符-选择匹配符
在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个,这时你需要用到哦 选择匹配符 |
符号 | 符号 | 示例 | 解释 |
---|---|---|---|
| | 匹配“|”之前或之后的表达式 | ab|cd | ab或者cd |
元字符-限定符
用于指定前面的字符和组合项连续出现多少次
符号 | 含义 | 示例 | 说明 | 匹配输入 |
---|---|---|---|---|
* | 指定字符重复0次或n次(无要求) | (abc)* | 仅包含任意个abc的字符串,等效于\w* | abc,abcabc |
+ | 指定字符重复1次或n次(至少一次) | m+(abc)* | 以至少1个m开头,后接任意个abc的字符串 | m,mabc,mabcabc |
? | 指定字符重复0次或1次(最多一次) | m+abc? | 以至少1个m开头,后接ab或abc的字符串 | mab,mabc,mmmab,mmabc |
{n} | 只能输入n个字符 | [abcd]{3} | 由abcd中字母组成的任意长度为3的字符串 | abc,dbc,adc |
{n,} | 指定至少n个匹配 | [abcd]{3,} | 由abcd中字母组成的任意长度不小于3的字符串 | aab,cdb,adabc |
{n,m} | 指定至少n个但不多于m个匹配 | [abcd]{3,5} | 由abcd中字母组成的任意长度不小于1,不大于5的字符串 | abc,abcd,aaaaa,bcdab |
注意:java匹配默认是贪婪匹配,即尽可能的匹配多的部分
比如:a{3,4} aaaaaa12
会匹配出aaaa,而不是aaa和aaa
元字符-定位符
定位符,规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置,这个也是相当有用的,必须掌握
符号 | 含义 | 示例 | 说明 | 匹配输入 |
---|---|---|---|---|
^ | 指定起始字符 | ^ [0-9]+[a-z]* | 以至少一个数字开头,后接任意个小写字母的字符串 | 123,5aa |
$ | 指定结束字符 | ^ [0-9]\\-[a-z]+$ | 以1个数字开头后连字符“-”,并以至少1个小写字母结尾的字符串 | 1-a |
\\b | 匹配目标字符串的边界 | han\\b | 这里说的字符串的边界指的是子串间由空格,或者是目标字符串的结束位置 | hanshunpingsphan nnhan |
\\B | 匹配目标字符串的非边界 | han\\B | 和\b的含义刚刚相反 | hanshunpingsphan nnhan |
分组
常用分组
常用分组构造形式 | 说明 |
---|---|
(pattern) | 非命名捕获,捕获匹配的子字符串,编号为 0 的第一个捕获是由整个正则表达式模式匹配的文本,其它捕获结果则根据左括号的顺寻从 1 开始自动编号 |
(?pattren) | 命名捕获,将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符号,并且不能以数字开头,可以使用单引号替代尖括号,例如 (?‘name’) |
String str = "(?<g1>\\d\\d)(?<g2>\\d\\d)";
sout(matcher.group(1));
sout(matcher.group("g1"));
//命名之后就会两种获取分组后子字符串的方法,没有命名只能通过顺序来获取
特别分组
这种分组,后面就只能通过matcher.group(0)方式来获取到值,不能通过matcher.group(1),matcher.group(2)…等等,因为不是捕获分组
常用分组构造形式 | 说明 |
---|---|
(?:pattern) | 匹配pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配,这对于用"or"字符(|)组合模式部件的情况很有用,例如:‘industr(?:y|ies)’是比’industry|industries’更经济的表达式 |
(?=pattern) | 它是一个非捕获匹配,例如:‘Windows(?=95|98|NT|2000)‘匹配’Windows 2000’中的’Windows’,但是不匹配’Windows 3.1’中的’Windows’ |
(?!pattern) | 该表达式匹配不处于匹配 pattren 的字符串的起始点的搜索字符串,它是一个非捕获匹配,例如:‘Windows(?!95|98|NT|2000)‘匹配’Windows 3.1’中的’Windows’,但是不匹配’Windows 2000’中的’Windows’ |
public class RegExp01 {
public static void main(String[] args) {
String content = "hello韩顺平教育 jack韩顺平老师 韩顺平同学hello";
//String regStr = "韩顺平教育|韩顺平老师|韩顺平同学"
//String regStr = "韩顺平(?:教育|老师|同学)";
//只匹配韩顺平后面是 教育或者老师 的 韩顺平 的字符串
//String regStr = "韩顺平(?=教育|老师)";
//不匹配韩顺平后面是 教育或者老师 的 韩顺平 的字符串
String regStr = "韩顺平(?!教育|老师)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println(matcher.group(0));
}
}
}
注意:在 限定符(* + ? {n} {n,} {n,m}) 后面加上一个问号(?)表示非贪婪匹配
应用实例
- 汉字
- 邮政编码:要求:是1-9开头的一个六位数,比如:123890
- QQ号码:要求:是1-9开头的一个(5位数-10位数),比如:12389,1345678
- 手机号码:要求:必须以13,14,15,18开头的11位数,比如13588889999
- URL:如:https://www.bilibili.com/video/BV1fh411y7R8?from=search&seid=183160912083761326
public class RegExp01 {
public static void main(String[] args) {
String content = "韩顺平教育";
String content1 = "123455";
String content4 = "https://www.bilibili.com/video/BV1fh411y7R8?from=search&seid=183160912083761326";
//汉字
//^[Α-¥]+$的意思是,从开头到结尾 这一整段内容,都要符合中间的这个规则 [Α-¥]+
//这里的意思是把 韩顺平教育 和 [Α-¥]+ 进行匹配
//并且有 ^ 和 $ 的话,指定的长度至少是要和 content 的长度一样,不能小于这个长度
String regStr = "^[\u0391-\uffe5]+$";
//这里的 ^和$ 指的是 content 的开始和结束,是整个字符串,因为这里有个 + 号
//邮政编码,是1-9开头的一个六位数
String regStr1 = "^[1-9]\\d{5}$";
//qq号码,是1-9开头的一个5位数-10位数
String regStr2 = "^[1-9]\\d{4,9}$";
//手机号码,13 14 15 18开头的十一位数
String regStr3 = "^1[3|4|5|8]\\d{9}$";
//url,需要注意,[]中的符号,代表的是本身
String regStr4 = "^([https|http]://)(([\\w-]+\\.)+[\\w])+(\\/[\\w-?=&/%.#]*)?$";
Pattern pattern = Pattern.compile(regStr4);
Matcher matcher = pattern.matcher(content4);
if(matcher.find()){
System.out.println("满足格式");
System.out.println(matcher.group(0));
}else{
System.out.println("不满足格式");
}
}
}
正则表达式三个常用的类
java.util.regex包主要包括以下三个类Pattren类,Matcher类和PatternSyntaxException
Pattern类
Pattren 对象是一个正则表达式对象,Pattren类没有公共构造方法,要创建一个Pattern 对象,调用其公共静态方法,它返回一个Pattern 对象,该方法接收一个正则表达式作为它的一个参数,比如:Pattern r = Pattern.compile(pattern)
- Pattern类的方法 matches,整体匹配,看content的内容,是否符合regStr的规则,有点类似 ^ $
String content = "hello abc hello 韩顺平教育";
String regStr = "hello";
String regStr = "hello.*";//true
boolean matches = Pattern.matches(regStr,content);
sout("整体匹配="+matches);//false
如果我们只需要匹配内容是否符合规则,而不需要找到匹配的内容,可以这样使用
Matcher类
Matcher 对象是对输入字符串进行解释和匹配的引擎,与Pattern 类一样,Matcher也没有公共构造方法,你需要调用Pattern对象的matcher方法来获取一个Matcher对香港
方法及说明:
- public int start():返回以前匹配的初始索引
- public int start(int group):返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引
- public int end(int group):返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量
- public int end():返回最后匹配字符之后的偏移量
- public boolean find():尝试查找与该模式匹配的输入序列的下一个子序列
- public boolean find(int start):重置匹配器,然后尝试查找匹配该模式,从指定索引开始的输入序列的下一个子序列
- public boolean matches():尝试将整个区域与模式匹配
- public String replaceAll(String replacement):替换模式与给定替换字符串想匹配的输入序列的第一个子序列
PattrenSyntaxException
PatternSyctaxEcxeption是一个非强制异常类,它表示一个正则表达式模式中的语法错误
分组,捕获,反向引用
给你一段文本,请你找出所有四个数字连在一起的子串,并且这四个数字要满足第一位和低四位相同,第二位和第三位相同,比如:1221,5775…
要解决前面的问题,我们需要了解正则表达式的几个概念:
- 分组:我们可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分我们可以看做是一个子表达式/分组
- 捕获:把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显式命名的组名,方便后面引用,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推,组0表示的是整个正则式
- 反向引用:圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以式在正则表达式内部,也可以是在正则表达式外部,内部反向引用
\\分组号
,外部反向引用$分组号
案例:
- 要匹配两个连续的相同数字:
(\\d)\\1
- 要匹配五个连续的相同数字:
(\\d)\\1{4}
- 要匹配个位与千位相同,十位与百位相同的数 5225 ,1551 :
(\\d)(\\d)\\2\\1
; - 请在字符串中检索·商品编号,形式如:12321-333999111这样的号码,要求:满足前面是一个五位数,然后一个-号,然后是一个九位数,连续的每三位都相同:
\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}
- 把“我…我要…学学学学…编程java!”,通过正则表达式修改成“我要学编程java”:
(.)\\1{2,}
//老韩思路:先把点去掉
//String regStr = "\\.+"
//再把重复的 . 去掉
String content = "我...我要...学学学学...编程java!";
//String regStr1 = "(.)\\1{2,}";//我.我要.学.编程java!
String regStr = "\\.+";//我.我要.学.编程java!
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
content = matcher.replaceAll("");
System.out.println(content);
}
String regStr1 = "(.)\\1+";//我.我要.学.编程java!
Pattern pattern1 = Pattern.compile(regStr1);
Matcher matcher1 = pattern1.matcher(content);
while(matcher1.find()){
content = matcher1.replaceAll("$1");
System.out.println(content);
}
String类中使用正则表达式
- String 类 public String replaceAll(String regex,String replacement)
String content = "jdk1.3 jdk1.4";
content = content.replaceAll("jdk1\\.3|jdk1\\.4","jdk");
sout(content);
- 判断功能,String 类 public boolean matches(String regex){}
//要求:验证一个手机号,必须是以138、139开头的
String content = "13564564565";
if(content.matches("1(38|39)\\d{8}")){
sout("验证成功");
}else{
sout("验证失败");
}
- 分割功能,String类 public String[](String regex)
String content = "hello#abc-jack12smith~北京";
//要求按照 # - ~ 数字 来分割
String[] split = content.split("#|-|~|\\d+");
//iter,增强for循环输出split数组
使用案例
规定电子邮件规则为
- 只能有一个@
- @前面是用户名,可以是a-z A-Z 0-9 _ -字符
- @后面是域名,并且域名只能是英文字母,比如sohu.com或者tsinghug.org.cn
- 写出对应的正则表达式,验证输入的字符串是否满足规则
String regStr = "^[\\w-][email protected]([a-zA-Z]+\\.)+[a-zA-Z]+$"
要求验证是不是整数或者小数
提示:这个题要考虑整数和负数
String regStr = "^[-+]?([1-9]\\d*|0)(\\.\\d+)?$";
对一个url进行解析
https://www.sohu.com:8080/abc/index.htm
- 要求得到协议是什么?https
- 域名是什么?www.sohu.com
- 端口是什么?8080
- 文件名是什么?index.htm
String content = "https://www.sohu.com:8080/abc/index.htm";
String a = "";
String b = "";
String c = "";
String d = "";
String[] split = content.split("[:/]");
for (int i = 0; i < split.length; i++) {
a = split[0];//协议
b = split[3];//域名
c = split[4];//端口号
d = split[split.length-1];//文件名
}
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
//老韩的方法是使用分组捕获,然后分组输出,matcher.group(1),matcher.group(2),matcher.group(3),matcher.group(4)
边栏推荐
- 两篇不错的php debug教程
- MySQL high-level statements (1)
- 有人开源全凭“为爱发电”,有人却用开源“搞到了钱”
- punch day05
- MySQL high-level --- storage engine, index, lock
- PHP Warning: putenv() has been disabled for security reasons in phar
- Ant three sides: MQ message loss, duplication, backlog problem, what are the solutions?
- MySQL 5.7 installation tutorial (full-step, nanny-level tutorial)
- love
- Leetcode Weekly 304
猜你喜欢
随机推荐
8/1 思维+扩展欧几里得+树上dp
Wuhan 2022 organizing of the high-performance computing added new ecological development of high-performance computing
Neo4j 中文开发者月刊 - 202207期
About the local server problem after ue4.27 pixel streaming package
request.getSession(), the story
MySQL高阶---存储引擎、索引、锁
typescript 'props' is declared but its value is never read solution
CAT1 4G+以太网开发板腾讯云手机微信小程序显示温度和下发控制
request.getSession(),的故事
mysql高阶语句(一)
At age 94, pioneer Turing award winner, computational complexity theory, Juris Hartmanis, died
MySQL驱动jar包的下载--保姆教程
APP专项测试:流量测试
July 18-July 31, 2022 (Ue4 video tutorials and documentation, 20 hours. Total 1412 hours, 8588 hours left)
MySQL (3)
optional
The nacos source code can not find the istio package
ASP.NET Core Web API 幂等性
宝塔+FastAdmin 404 Not Found
postgres 多个变量填充字符串,字串格式化