java数据结构与算法基础-----字符串------正则表达式---持续补充中

数据结构与算法代码实战讲解之:字符串与正则表达式 1.背景介绍 正则表达式(Regular Expression)也称规则表达式、匹配表达式或模式表达式,是一种文本匹配的工具,它可以用来检查一个串是否含有指定的字符、字符串、模式等,常用的正则表达式有 Perl 兼容的正则表达式、POSIX Basic Regular Expressions(BREs)、POSIX Extended Regular E 阅读详情
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.youkuaiyun.com/grd_java/article/details/123063846

目前校招的面试,经常会遇到各种各样的有关字符串处理的算法。掌握正则表达式可以秒杀大部分普通方法处理起来偏难的题目。
而且正则表达式也是实际工作中使用频率非常高的工具。

记得几年前学习正则表达式,因为当时英语不好,所以是从b站视频入手学习的,今天回到b站搜了一下,发现依然是韩顺平老师讲解的比较全面。本文也是当年我学习这套视频所做的笔记(只不过当时记在了A4纸上),这么多年如果涉及使用正则表达式的场景,也是直接翻笔记就搞定了。链接如下:

韩顺平JAVA,正则表达式:https://www.bilibili.com/video/BV1Eq4y1E79W/

但是要注意,正则表达式的效率不如直接进行字符操作。所以做题时,使用正则表达式尽量不要对同一个子串进行超过一次以上的匹配。否则反而影响效率。

如何正确使用正则表达式提升效率呢?只要是字符操作十分繁琐麻烦,而使用正则可以一步到位的情况都可以使用。例如下面Leetcode205题,我们想要跳过一些比较有规律,但是处理起来比较繁琐的字符串时,就可以使用正则表达式来处理

  1. 没有使用正则
    在这里插入图片描述
  2. 使用了正则后
    在这里插入图片描述

一、正则底层实现概述

这里很重要,一定要掌握,否则大家后面学再多语法,都不知道为什么这样用。

拿一段简单的测试代码,来讲解两个重要的方法的底层实现。这里使用的是java语言,其它语言大同小异。
  1. 下面代码的功能是,实现从文本中提取出所有的IP地址
    在这里插入图片描述
package com.yzpnb.pattern;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String content = "私有地址(Private address)属于非注册地址,专门为组织机构内部使用。\n" +
                "以下列出留用的内部私有地址\n" +
                "A类 10.0.0.0--10.255.255.255\n" +
                "B类 172.16.0.0--172.31.255.255\n" +
                "C类 192.168.0.0--192.168.255.255";
        Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");//匹配规则,这里实现匹配文本中所有的IP地址
        int no = 0;//无关紧要,下面输出时我想输出一个序号
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            //匹配内容,文本,放到group组中。
            System.out.println("找到:"+(++no)+" "+matcher.group(0));//输出
        }
    }
} 

1. matcher.find()

功能概述
  1. 根据指定规则,定位字符串中满足规则的子字符串
  2. 定位成功后,此方法返回true
  3. 同时会将子字符串的开始索引记录到matcher对象的一个,类型为int型一维数组的属性中(int[] groups)
  4. 假设找到的子字符串起始下标为start,结尾下标为end。那么会让groups[0] = start;groups[1] = end+1;
  5. end+1很重要,它可以方便我们下次匹配,减少工作量。所以只要涉及到结尾下标,几乎都保存结尾下标+1的值。比如String.substring(start,end)方法,都是包含start不包含end的区间。
原理解析
  1. matcher实例化后:
  1. 可以看到下图中,matcher对象中会有一个初始大小为20的groups数组,初始值为-1
    在这里插入图片描述
  2. 同时,first变量初始值也是1,last为0,oldLast也是-1
    在这里插入图片描述
  1. 当执行find()方法后:
  1. 我们会发现,它会在groups[0]记录找到的子串的起始下标。groups[1]会记录结尾下标+1。为什么要记录结尾下标+1呢?是因为方便我们下次查找时,直接跳过已经查找过的。
    在这里插入图片描述
  2. 同时,会将本次结尾下标+1这个值,作为下次查找的起始地址保存到oldLast属性中

另外first属性保存本次匹配成功的串的起始位置,last属性保存本次匹配成功的串的结束位置+1.
在这里插入图片描述

2. matcher.group(0)

功能概述
  1. 根据groups[0]=59和groups[1]=67记录的值,从字符串中,截取groups[0]到groups[1]之间的子字符串. 左闭右开区间:[ 59 , 67 ) === 闭区间:[ 59 , 66 ]
为什么我们例子中group()方法中传参为0呢?为什么不group(1)?
  1. 下面是group方法的源码:
  1. 第一个if语句:如果成功使用find()方法匹配,first会>=0,否则抛出没匹配到的异常
  2. 第二个if语句:我们调用group()方法时,这个传参必须>=0. 并且 这个值也必须<=组的个数(groups[]数组的下标范围,不可越界)否则抛出下标越界异常
  3. 第三个if语句,如果获取指定groups[]数组中的值为-1,就返回null
  4. 最后的return,就是为什么传参需要为0
  1. 我们上面的例子中,我们匹配后的子串下标,保存在groups[0]和groups[1]中
  1. 这是因为find()这个方法是可以一次找到多个的。第0个放在groups[0]和groups[1]中。如果有第1个,就放在groups[2]和groups[3]中,依次类推。
  2. 现在group()方法,想要实现我们传0,获取第0个,我们传1获取第1个是如何实现的呢?

每一个都有两个下标,0 * 2 = 0 , 0 * 2+1 = 1. 这样就获取第0个子串的groups[]数组下标
同理,如果我们传参为1,就说明我们想要第1个子串。1 * 2 = 2 , 1 * 2 + 1 = 3. 这样就获取了第1个子串的groups[]数组下标了。

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();
}

3. 分组情况下

前面的案例,是只考虑分一组的情况,只会使用到groups[0]和groups[1]两个数组元素。下面分析分多组的情况。

下面的案例中,我将ip地址10.0.0.0分组,每组保存IP地址的数字,也就是10,0,0,0去掉那些点,只保留每两个点之间的数字
在这里插入图片描述

package com.yzpnb.pattern;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {
    public static void main(String[] args) {
        String content = "私有地址(Private address)属于非注册地址,专门为组织机构内部使用。\n" +
                "以下列出留用的内部私有地址\n" +
                "A类 10.0.0.0--10.255.255.255\n" +
                "B类 172.16.0.0--172.31.255.255\n" +
                "C类 192.168.0.0--192.168.255.255";
        Pattern pattern = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)");//匹配文本中所有的IP地址
        int no = 0;//无关紧要,下面输出时我想输出一个序号
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            //匹配内容,文本,放到group组中。
//            System.out.println("找到:"+(++no)+" "+matcher.group(0));//输出
            System.out.println("matcher.group(0):"+matcher.group(0));
            System.out.println("matcher.group(1):"+matcher.group(1));
            System.out.println("matcher.group(2):"+matcher.group(2));
            System.out.println("matcher.group(3):"+matcher.group(3));
            System.out.println("matcher.group(4):"+matcher.group(4));
            System.out.println("matcher.group(5):"+matcher.group(5));
        }
    }
}

  1. 可以发现,上面我们分了4组,实际上保存了5组到groups[]数组中
  2. 其中group(0)获取到的第0组,为整个匹配规则匹配到的完整子串
  3. 而剩下的group(1)到group(4)为我们想要的分组,分别为4个点与点之间的数字
  4. 而group(5)是为大家演示,下标越界异常。没有第5组
第0组遵循end+1原则。而其它分组,也同样遵循end+1

在这里插入图片描述

  1. 第0组因为是保留完整匹配成功的子串。依然会遵循前面案例分析的,groups[1]依然保存end+1的位置,方便下次匹配。
  2. 而其它组,它的末尾根本就不是下一次匹配应该开始的位置。但是,完全没必要因为这个就特殊处理其它组,所以也都保存end+1的位置。

二、正则表达式语法

元字符(Metacharacter)分为:限定符、选择匹配符、分组组合和反向引用符、特殊字符、字符匹配符、定位符

1. 正则转义符

转义号:\\,用来指定后面的字符,当做字符,而不当做关键字。

简单来讲,我们以普通转义字符(字符串,不是正则)为例。java中字符串用两个双引号 “字符串” 来标识。那么如果字符串中,包含双引号怎么办呢?例如" 这是一个"字符串"哦! “,此时java就会报错,因为它不知道从哪开始到哪结束算作一个字符串。而需要转义” 这是一个\ "字符串\ "哦! "
在这里插入图片描述
在这里插入图片描述

  1. 正则表达式与普通字符串中的转义原理一样,但是普通字符串用一个反斜杠\表示转义字符,而正则表达式用两个反斜杠\\表示转义字符
  1. 用正则表达式检索某些特殊字符,需要转义符号,否则会无法完成检索,甚至报错(因为这些符合直接出现在正则表达式中,富有特殊的含义。因此只是当做普通字符使用时,必须转义)

常见的需要用转移符号的字符如下:[.,*,+,(,),$,/,\,?,[,],^,{,}]

  1. Java的正则表达式和其它大部分语言不同,其它语言的转义号是\(一个反斜杠),而Java是\\(两个反斜杠)
  2. 下面是例子,尝试匹配$符号
  1. 直接用 $ 来匹配 $ 符号,可以发现结果为空
    在这里插入图片描述
  2. 用 \ \ $来匹配,可以发现匹配成功
    在这里插入图片描述

2. 字符匹配符

在正则表达式中有特殊意义的字符,这些字符往往就是前面讲的需要转义字符\\标识,才能识别为普通字符的字符。直接使用这些字符,将富有特殊的含义。而反过来,普通的字母。例如w如果进行转义\\w,也会富有特殊的含义。这些都是设计者所规定的规则,我们使用时,记住并遵守这些约定即可。

符号描述示例(示例中有不认识的符号,可以参考正则限定符中内容)示例解析
[ ]规定当前位置匹配可选字符列表[abcd]当前位置可选a,b,c,d中任意一个字符
[^ ]规定当前位置匹配,不接收的字符列表[^abcd]当前位置可选,除了a,b,c,d之外的任意一个字符
-连字符A-Z任意从A到Z的单个大写字母
.匹配除 \n(换行符)以外的任何字符a..b以a开头,b结尾,中间两个点表示,这两个位置可以匹配任意字符长度为4的字符串(例如:aaab、a35b、a#*b…)
\\d默认匹配单个数字字符,等价与[0-9],是\\d{1}的简写形式.如果后面加个{}表示匹配几个,例如\\d{3}表示匹配3个数字字符\\d{3}(\\d)?匹配3或4个数字
\\D\\d的相反匹配规则。匹配单个非数字字符,等价于[^0-9],同样可以使用{}\\D(\\d)*单个非数字字符开头,后接任意个数字字符(例如:a,A342)
\\w匹配单个数字、大小写字母和下划线_,相当于匹配[0-9a-zA-Z]\\d{3}\\w{4}以3个数字字符开头,后面4个是任意数字,大小写字母组成的,长度为7的数字字母字符串
\\W\\w的相反匹配规则。匹配单个非数字、大小写字母和下划线,相当于[^0-9a-zA-Z]\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串
(?i)后面的匹配规则进行匹配时,不区分大小写,其中i是字母i,是单词Insensitive (adj.不敏感的;漠不关心的;)的缩写(?i)abc 或 a(?i)bc 或 a((?i)b)c1、abc都不区分大小写 2、bc不区分大小写 3、只有b不区分大小写
\\s匹配任何空白字符(空格,制表符)a\\sb匹配a空格b或者a制表符b等结果
\\S\\s的相反匹配规则,匹配任何非空白字符a\\Sb只要是a和b之间不是一个空白字符,就匹配
待续待续待续待续待续待续待续待续待续待续待续待续待续待续待续续待续待续续待续待续续待续待续续续待续待续待续待续待续待续待续
额外的实现(?i)效果的方法(不区分大小写):其中i是字母i,是单词Insensitive (adj.不敏感的;漠不关心的;)的缩写

正常状况下,我们匹配abc,默认是区分大小写的,也就是无法匹配到ABC

  1. 第一个方法是在正则表达式中使用(?i)
  1. 下图中实现通过(?i),用abc匹配到了ABC的效果
    在这里插入图片描述
  2. 而直接使用abc匹配,则无法匹配到ABC
    在这里插入图片描述
  1. 额外的方法是:生成Pattern对象时,指定参数Pattern.CASE_INSENSITIVE, 实现不区分大小写,但是这种方法只能实现整体不区分大小写,无法和(?i)一样实现精细控制某一个字符不区分大小写的目的
    在这里插入图片描述

3. 选择匹配符

一个竖杠|就是选择匹配符,和或运算符||有异曲同工之妙.表示只要满足一个条件就匹配

例如我们想要实现匹配Java或者抓哇。两个随便一个都行,就可以通过选择匹配符来实现。下面的例子中,想要在字符串java抓哇中,匹配出java或者抓哇。那么就可以使用正则表达式java|抓哇
在这里插入图片描述

4. 正则限定符

java默认贪婪匹配,例如+代表匹配1个或多个,如果当前字符串符合条件的连续字符有多个,默认贪婪匹配多个,而不是1个1个匹配。

如何取消贪婪匹配,选择用非贪婪匹配呢?只需要限定符后面加个?即可。例如我们想要从java0123完成匹配

  1. java\\d*表示java开头,后面跟随0或多个数字。会直接匹配出java0123,因为是贪心匹配,优先尽可能多的匹配
    在这里插入图片描述
  2. java\\d*?表示java开头,后面跟随0或多个数字,并且非贪婪匹配。则会匹配出java,因为是非贪婪匹配,优先尽可能少的匹配,而*表示匹配0或多个,最少就是0个,所以非贪婪优先最少,也就是0个
    在这里插入图片描述
符号描述示例(示例中有不认识的符号,可以参考正则限定符中内容)示例解析
{num}按指定规则一次性匹配num个字符\\d{3}按照\\d规则,匹配连续的3个字符,这3个字符全部满足\\d规则
?按照指定规则,匹配0或1个字符\\d?按照\\d规则,匹配0或1个字符
*按照指定规则,匹配任意个字符(0个,1个或多个)\\d*按照\\d规则匹配任意个
+按照指定规则,匹配1个或多个字符\\W+按照\\W规则,匹配非数字或字母字符,1个或多个
{num}:按照指定规则,连续num个字符匹配。就是至少连续num个符合指定规则的字符才能完成匹配

使用例子"123abc1234abc123456789",我们要对其中123,1234,123456789进行匹配

  1. 直接用{num}形式,表示必须num个,不能多也不能少。下面例子中,我们按照1[0-9]规则并限定[0-9]{2}.也就是1开头,后面跟[0-9]数字,必须长度为2,不能多也不能少。

下图结果中可以看出,1开头满足后,只会匹配2个[0-9]的数字,多一个少一个都没有匹配到
在这里插入图片描述

  1. 用{num,}形式,表示至少匹配num个,上不封顶,我们[0-9]{num,}进行匹配时,会匹配[0-9]至少两个,多了也没关系,但是不能少

下图结果中可以看出,1开头满足后,后面匹配[0-9]至少2个,但是上不封顶
在这里插入图片描述

  1. 用{left,right}形式,至少匹配left个,最多匹配right个。默认贪婪匹配,如果一次性匹配不完(原字符串符合规则字符个数超出right,优先先匹配right个,剩下的再依次匹配)

下图中,我们限定开头必须是1,且对[0-9]限定至少2个,最多4个。匹配结果也同样满足条件
在这里插入图片描述

5. 正则定位符

规定要匹配的字符串出现的位置,比如在字符串开始还是结束位置。换句话说:指定要匹配的位置

符号描述示例(示例中有不认识的符号,可以参考正则限定符中内容)示例解析
^指定起始字符^[0-9]+[a-z]*至少1个数字开头,后接任意个小写字母
$指定结束字符^[0-9]\\-[a-z]+$以一个数字开头,接连字符"-",至少1个小写字母结尾
\\b匹配以指定规则结尾的边界yin\\b*边界:用空格分开的子串的两边,或目标字符串的起始和结束位置,例如这个字符串“yinabcdyin aaaayin”,标黄的位置就是以yin结尾的边界
\\B与\\b的含义正好相反,匹配以指定规则开头的边界yin\\B“yinabcdyin aaaayin”,其中标黄的是以yin为开头的边界
待续待续待续待续待续待续待续待续待续待续待续待续待续待续待续续待续待续续待续待续续待续待续续续待续待续待续待续待续待续待续

三、分组

适用于,我们匹配到内容后,想要单独获取其中某一部分的场景
例如匹配ip地址,10.0.76.1 我们匹配成功后,想要单独获取第3个字段中的内容76,就可以用分组来实现

1. 捕获分组

  1. (pattern):用一对小括号来实现分组称为非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其它捕获结果则根据左括号的顺序从1开始自动编号。

pattern是匹配规则,也就是要分组的正则表达式

  1. (? < name>pattern):命名捕获。将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符合,并且不能以数字开头。可以使用单引号代替尖括号。例如(?'name’pattern)
命名捕获,实战中基本都是使用命名捕获,只有很简单的匹配会使用非命名捕获

最上面的底层实现中,我们已经介绍过非命名捕获了。接下来是命名捕获,通过使用group方法的重载实现,这个group方法的源码如下,通过字符串获取对应组下标,然后剩下的逻辑和非命名一致。
在这里插入图片描述

  1. 我们想要实现,从一个字符串中,匹配出IP地址,并且通过"one"获取ip第一个字段,"two"获取第二个,"three"和"four"获取第3个和第4个
    在这里插入图片描述
  2. 上图中发现,我们通过(?< name>)的方式为分组命名,并通过group方法,使用指定name获取分组内容。
public static void main(String[] args) {
        String content = "alksdjflksjal====192.168.0.1====kfjlkasjflkjdsladf";
        Pattern pattern = Pattern.compile
                ("(?<one>[0-9]{1,3})." +
                "(?<two>[0-9]{1,3})." +
                "(?<three>[0-9]{1,3})." +
                "(?<four>[0-9]{1,3})");//匹配文本中所有的IP地址
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            System.out.println("matcher.group(0):"+matcher.group(0));
            System.out.println("matcher.group(\"one\"):"+matcher.group("one"));
            System.out.println("matcher.group(\"two\"):"+matcher.group("two"));
            System.out.println("matcher.group(\"three\"):"+matcher.group("three"));
            System.out.println("matcher.group(\"four\"):"+matcher.group("four"));
        }
    }

2. 非捕获分组

想要使用一下分组的功能,但是不想浪费额外空间和时间,放到group(0)之类的。也就是说,捕获分组会将分组的内容捕获并存储。而非捕获分组,只是提供分组功能,但是不进行捕获和存储

常用于"or"字符(|选择匹配符)组合模式部件的情况。
我们知道,分组是独立的,它富有()的功能,也就是括号里的单独处理(数学中,括号里的先算)

  1. (?:pattern):匹配pattern,分组中内容和pattern中匹配即可。简写了选择匹配符的实现,例如我们要匹配java0,java1,java2,java3,…

下面两个表达式等价,它极大的减少了重复操作,实现共有部分写一遍,单独用分组处理不同的部分。

  1. java(?:0|1|2|3)
  2. java0|java1|java2|java3

在这里插入图片描述

    public static void main(String[] args) {
        String content = "java0,java1,java2,java3,java4";
        Pattern pattern = Pattern.compile
                ("java(?:0|1|2|3)");//匹配文本中所有的IP地址
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            System.out.println("matcher.group(0):"+matcher.group(0));
        }
    }
  1. (?=pattern):条件判断pattern,也就是这是将这个分组当做一个匹配条件,不参与到匹配结果中

例如我们想要匹配这个字符串java0,java1,group0,group1,apple0,apple1中,所有后面数字是0的英文字母,并且这个数字0不放入最终匹配结果中

  1. 直接用普通正则[a-z]{4,10}0匹配,无法实现这个效果,可见下面的正则会将数字0也匹配出来
    在这里插入图片描述
  2. 用非捕获分组,[a-z]{4,10}(?=0),可以轻松匹配出这些单词,并且不带后面的0
    在这里插入图片描述
    public static void main(String[] args) {
        String content = "java0,java1,group0,group1,apple0,apple1";
        Pattern pattern = Pattern.compile
                ("[a-z]{4,10}(?=0)");//匹配文本中所有的IP地址
        Matcher matcher = pattern.matcher(content);//按照pattern定义的匹配规则,到content中匹配
        while(matcher.find()){//matcher.find()如果匹配成功就返回true,否则返回false
            System.out.println("matcher.group(0):"+matcher.group(0));
        }
    }
  1. 有啥用?
  1. 当我们想要统计所有1999年生产的手机型号时。例如这个字符串"诺基亚1999,iPhone2018,摩托罗拉1999…",我们想匹配出1999年的所有手机,诺基亚和摩托罗拉。就可以用这个。而不是匹配出诺基亚1999,摩托罗拉1999,最后还得通过其它处理,将1999去掉。
  1. (?!pattern),和(?=pattern)是相反的操作,表示拒绝匹配pattern

我们想要对java0,total1,group0,hotel1,apple0,banana1进行指定匹配

  1. 先用(?=pattern)举例:匹配所有单词,以数字结尾,并且这个数字必须是0. 这个就可以使用(?=pattern)操作,可以使用正则[a-z]{4,}(?=\d)(?=0),表示最少4个字母,并且以数字结尾,并且末尾数字必须为0
    在这里插入图片描述
  2. 匹配所有单词,以数字结尾,但是这个数字不能为0.这时就用(?!pattern)操作,可以使用正则[a-z]{4,}(?=\d)(?!0)实现最少4个字母,以数字结尾,并且末尾数字必须不能为0
    在这里插入图片描述

四、实战案例

因为篇幅原因,我将其放在另一篇文章中:https://blog.youkuaiyun.com/grd_java/article/details/136963602
优快云粉丝冲3万粉福利放送!C++、Python、数据结构与算法、计算机基础、数据库教程汇总! 最近有粉丝问我要一些C++和Python、Java的学习资料,一个一个回复有些慢,索性就写一篇文章吧! 声明:此文章中涉及到的内容均来自网络,我看到比较好的才分享给大家,你们可以根据情况选择。 第一篇:C++ 这里可以分为基础→进阶→提升,C++的基础概念,基础部分包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。进阶部分分为类的高级技术、类的继承、编译链接和命名空间等。提升部分有类型转换、文件操作、异常处理、代码重用等内容。 ... 阅读详情

相关推荐

从正则表达式到NFA:Java实现的字符串匹配解决方案

正则表达式是文本处理的瑞士军刀,广泛应用于编程语言中处理字符串操作。它提供了一种灵活、强大且简洁的方式来描述和匹配字符串的模式。通过正则表达式,开发者可以执行搜索、替换、分割等操作,也可以验证数据格式的有效性。例如,验证电子邮件地址或电话号码是否符合预期格式。在本章,我们将探讨正则表达式的基础知识、语法以及在不同场景下的应用,确保读者能够掌握其核心概念和实际使用技巧。在深入学习正则表达式之前,了解其背后的理论基础——不确定性有穷自动机(NFA)将大有裨益。graph LR。

weixin_42372837的博客 1028

Java学习总结(字符串类、正则表达式)

学习Java中的字符串类、正则表达式

2202_75688394的博客 762

基于Flink的风控系统

可以使用Flink-Stream进行实时数据流的检测和处理,或者使用Flink-Kafka集群进行数据转发和存储,然后使用Flink-Table进行数据表的查询和分析。在Flink中,可以使用Flink-Stream进行数据流的处理,或者使用Flink-Kafka进行Kafka数据流的消费和处理。Flink的运行时本身也支持迭代算法的执行。可以使用Flink-Stream进行实时数据流的检测和处理,或者使用Flink-Kafka集群进行数据转发和存储,然后使用Flink-Table进行数据表的查询和分析。

m0_68231587的博客 1875

java之字符串与正则表达式

正确字符串的格式,常用来判断用户输入的内容是否符合格式的要求,注意是严格区分大小写的。使用指定字符集解码指定字节数组,并从下标m处截取字节,截取n个最终形成一个字符串。将字符串内[索引1,索引2)内所有字符由str字符串替换。字符串.replace(索引1,索引2,str字符串)字符串.substring(索引1,索引2)字符串[索引1,索引2)内字符组成的字符串。字符串.delete(索引1,索引2)字符串.insert(索引,字符串)字符串.append(字符串);字符串.Matches(正则)

m0_60027772的博客 5914

研究生课程笔记:软件包在流行病学中的应用(三)——STATA软件

关键词:STATA软件基本操作、STATA对于流行病学研究的实现、STATA对复杂抽样设计样本量计算的实现 一、STATA软件基本操作 这部分网上教程有很多,也可以直接根据stata自带的help功能进行自学,在此只记录课程中提及的功能项。 1. 变量编辑 1.1 赋值:label type(按精度区分) 1) 整型:int(32), short(16), long(32) 2) 实型:flo...

weixin_45463530的博客 2433

告别OFDM卡顿:用MATLAB手把手仿真AFDM波形,搞定高铁、无人机通信的时变信道难题

本文详细介绍了如何使用MATLAB仿真AFDM波形,解决高铁和无人机通信中的时变信道难题。通过仿射变换技术,AFDM在多普勒频移严重的场景下表现优异,显著提升通信质量。文章包含参数配置、波形生成、性能对比等实战内容,适合通信工程师和研究人员参考。

weixin_27014595的博客 320

Java的正则表达式和字符串操作

1.背景介绍 1. 背景介绍 在Java编程中,正则表达式和字符串操作是非常重要的一部分。正则表达式可以用来匹配、替换和搜索文本中的模式,而字符串操作则可以用来处理、分析和操作字符串数据。在本文中,我们将深入探讨Java中的正则表达式和字符串操作,并提供一些实用的技巧和最佳实践。 2. 核心概念与联系 在Java中,正则表达式和字符串操作的核心概念包括: 正则表达式:一种用于匹配字符串...

AI天才研究院 674

大模型——AI对话四象限

{ "摘要": "文章揭示了90%的人不会有效与AI沟通的问题,指出简单粗暴的提问只能得到标准答案。作者提出'AI对话四象限'模型:1)双方都懂时提效;2)AI懂但需学会分层提问;3)共同探索未知领域;4)向AI传授独家知识。强调沟通技巧的重要性,认为会提问的人不会被AI替代。最后呼吁读者尝试四象限思维,与AI碰撞火花。" }

312

java的字符串和正则表达式

JIESHULEV

m0_74831526的博客 505

信号处理仿真:自适应信号处理_(8).自适应信道均衡

在无线通信系统中,信道的多径效应和时变特性会导致信号的失真,从而影响通信质量。自适应信道均衡技术通过实时调整均衡器的参数,以补偿信道失真,提高信号的质量和可靠性。本节将详细介绍自适应信道均衡的原理、算法和实现方法,并通过具体的仿真例子来说明其应用。

2401_87715305的博客 1041

论文阅读 AIED 2024 Coding with AI: How Are Tools Like ChatGPT Being Used by Students in Foundational Pro

该论文题为《Coding with AI: How Are Tools Like ChatGPT Being Used by Students in Foundational Programming Courses》,由美国犹他州立大学的 Aashish Ghimire 与 John Edwards 共同撰写,发表于人工智能与教育领域顶级会议。

CSPhD-winston的博客 309

Java正则表达式

Java 中正则表达式的使用 在 Java 中正则表达式为 String 类型,被验证的内容同样为 String 类型。 通过 String 类中 的 matches 方法实现内容的匹配校验。如:“被验证内容”.matches(“正则表达式”) 正则表达式语法规则:[内容限定]{长度限定}, 在定义限定内容规则时,如果没有指定长度限定,那么默认长度为 1。 单字符限定: String regex = "[a]"; String content = "a"; System.out.println(conten

y9p6p的博客 3186

17、超声散斑降噪与桌面系统背景估计技术

本文介绍了超声散斑降噪与桌面系统背景估计的先进技术。在超声成像方面,提出结合超分辨率(SR)和非线性扩散(ND)的方法,显著降低噪声并保留图像细节,在MSE和CNR指标上优于传统方法。在桌面交互系统中,针对传统背景估计因忽略设备像素结构导致的误差,提出基于显示器与相机像素结构建模的几何转换方法,有效减少尖锐边缘区域的误检,提升物体识别准确性。实验验证了两种方法的有效性,未来将致力于实时性优化与多设备兼容性扩展。

dream的博客 88

java数据结构与算法基础-----字符串------正则表达式的练习案例---持续补充中

【代码】java数据结构与算法基础-----字符串------正则表达式的练习案例---持续补充中。

殷志鹏的博客 873

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java学习手册:数据结构与算法汇总

数据结构与算法程序题汇总如下:(不断更新中) 1、PAT(Basic Level)Practise-----1001 2、Java学习手册:(数据结构与算法-链表)如何实现单链表的增删操作? 3、Java学习手册:(数据结构与算法-链表)如何实现单链表排序? 4、Java学习手册:(数据结构与算法-链表)如何从链表中删除重复元素? 5、Java学习手册:(数据结构与算法-链表)如何找出单链表中的倒...

浩比的专栏 3248

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

java常用的数组、字符串、集合操作以及数据结构与算法基本知识

java中常用封装的数组 、字符串、 集合来操作对象,但数据结构中常用的有栈和队列   数与图以及他们之间的排序,查找。         数组声明没有分配内存空间  只有创建或者是初始化时才分配,创建时把数组中的数据类型数据所在的内存空间首地址赋值给数组名,在创建每个对象时,都会给该对象分配地址和它存储的数据 。如变量    int arr[]; int arr[]={1,2,3};  arr=

lu93it的博客 5065

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

5分钟快速入门JavaScript数据结构与算法的基础【①JavaScript数据结构与算法系列】

本文目录一、JavaScript的简介二、JavaScript的环境搭建三、JavaScript的基础(变量、常量、运算符、真假值)四、本章小结五、写在后面 一、JavaScript的简介 JavaScript是一门非常强大的编程语言。它也是最流行的编程语言之一,也是互联网上最卓越的语言之一。 在GitHub(世界上最大的代码托管站点)上,托管了 30w+ 的JavaScript代码仓库(用JavaScript开发的项目数量也是最多的,参看http://githut.info)。使用JavaScript的项

狼丶宇先森的网络科技空间 1880

Java学习笔记 | 4万字长文详细介绍Java数据类型:字符串及其数据结构 | 字符串底层原理 | 正则表达式书写语法| Regex | 字符串匹配 | KPM模式匹配 | 朴素的模式匹配

String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。Java 程序中所有的双引号字符串,都是 String 类的对象。**所属包: ** String 类在java.lang包下,所以使用的时候不需要导包。符号说明匹配任何字符\d匹配一个数字:[0-9]\D匹配任何非数字[^0-9]的简写\s一个空白字符:[ \t\n\x0B\f\r] 的简写\S非空白字符:[^\s] 的简写\w单词字符(英文、数字、下划线):[a-zA-Z_0-9]的简写\W。

神马都会亿点点的毛毛张 1240

[Java面试——数据结构和算法]

消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,目前可以解密逆向的只有CRC32算法,只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。消息摘要算法不存在密钥的管理与分发问题,适合于分布式网络上使用。消息摘要算法主要应用在“数字签名”领域,作为对明文的摘要算法。何谓数字签名?数字签名主要用到了非对称密钥加密技术与数字摘要技术。数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。

abclyq的博客 1704

【实战】JavaScript版数据结构与算法 —— 课程导学

文章目录一、前端刚需二、快速入门三、课程内容介绍四、课程特色五、适用对象六、注意事项 JavaScript版数据结构与算法-慕课网实战 一、前端刚需 前端开发门槛低、人员参差不齐 前端开发只会写页面,不懂算法,伪程序员 面试考算法,通过率极低 看过C、C++、Java版算法,JavaScript版的却不会写 程序 = 算法 + 数据结构 二、快速入门 通过“解题”夯实基础算法 理解算...

程序边界 1043

(Java)数据结构——正则表达式

本博客是博主用于复习数据结构以及算法的博客,如果疏忽出现错误,还望各位指正。

m0_60631836的博客 650

Java字符串操作全解析:语法、示例与应用场景

在Java算法题和日常开发中,字符串处理是必备的核心技能。本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字符串处理技巧,轻松应对笔试面试高频题目。

weixin_44435110的博客 5920

资料分享:送你一本《数据结构与算法:Python语言描述》电子书!

下图为 TIOBE 3月编程语言排行榜。 从榜单来看,曾经铁打的 Java、C、C++ 局势,早已在数月前被 Python 的闯入而打破。究其根由,并非是 C++ 的应用领域正在逐渐缩减,而是随着人工智能、机器学习的崛起,适用于该领域的 Python 才会水涨船高,带起了市场份额,而且这种份额有扩大的趋势。 所以,学习 Python 也就变成对我们的一个新要求。要想深入的了解一门语言最好的方式就...

老马的程序人生 1万+

【总结】Java数据结构与刷题常用方法(持续更新中)

在Java中,栈(Stack)和队列(Queue)都是通过集合框架(Collections Framework)中的接口和类来实现的。这些接口和类位于java.util包中。都可以用ArrayDeque和LinkedList来实现,其中有专门为队列写的Queue接口,没有为栈写的接口,栈可以用Queue的实现类进行实现。注意ArrayDeque可以存地址但是不能存null,遇到需要存null值时统一用LinkedLList。

qq_51907069的博客 739

常用字符串算法

一、判断两个字符串是否包含相同的内容 1.巧用数组下标实现,把用字符的ASCII码值当作下标,记录出现的字符,然后对两字符串进行遍历 /** * 判断s于s2是否相同 * @param s * @param s2 * @return boolean */ static boolean equals(String s,Strin...

Elltor 3597
上一篇: java数据结构与算法基础-----排序------堆排序
下一篇: java数据结构与算法基础-----字符串------正则表达式的练习案例---持续补充中
ydenergy_殷志鹏
博客等级 码龄7年 5887粉丝 543原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值