广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java字符串 正则表达式详解
  • 440
分享到

Java字符串 正则表达式详解

2024-04-02 19:04:59 440人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录一、规则表1.字符2.字符类 .3.边界匹配符4.逻辑操作符5.量词二、Pattern类1.Pattern类的实例获取—compile方法2.split方法3.Pattern中匹

在日常Java后端开发过程中,免不了对数据字段的解析,自然就少不了对字符串的操作,这其中就包含了正则表达式这一块的内容,这里面涉及Java包中Pattern类和Macher类,本篇博客就针对这一块内容和常见的用法进行总结,本博客主要的参考资料是《Java编程思想》第4版。

以一个问题引出本博客的内容。问题是:检查一个字符串是否以大写字母开头,以句号结尾


String len="^[A-Z].*[\\.]$";
System.out.println("Taaa.".matches(len));//true
System.out.println("taaa.".matches(len));//false
System.out.println("Taaa".matches(len));//false

1.*[\.] 就 是 正 则 表 达 式 , 用 来 匹 配 字 符 串 。 代 表 一 行 的 起 始 , [ A − Z ] 表 是 A 到 Z 任 何 的 字 母 , 就是正则表达式,用来匹配字符串。^代表一行的起始,[A-Z]表是A到Z任何的字母, 就是正则表达式,用来匹配字符串。代表一行的起始,[A−Z]表是A到Z任何的字母,表示的一行的结束。

一、规则表

规则表定义正则表达式该怎么写。这类东西不需要刻意去记,用的时候去写就好,用多了自然就记住了。

1.字符

B 指定字符B
\xhh 十六进制为oxhh的字符
\uhhhh 十六进制表示为oxhhhh的Unicode字符
\t 制表符Tab
\n 换行符
\r 回车
\f 换页
\e 转义

2.字符类 .

. 任意字符
[abc] 包含a、b和c的任何字符(和a|b|c作用相同)
[^abc] 除了a、b和c之外的任何字符(否定)
[a-zA-Z] 从a到z或从A到Z的任何字符(范围)
[abc[hij]] 任意a、b、c、h、i和j字符(与a|b|c|h|i|j作用相同)
[a-z&&[hij]] 任意h、i或j
\s 空白符(空格、tab、换行、换页和回车)
\S 非空白符
\d 数字
\D 非数字
\w 词字符[a-zA-Z0-9]
\W 非词字符

3.边界匹配符

^ 一行的起始
$ 一行的结束
\b 词的边界
\B 非词的边界
\G 前一个匹配的结束

4.逻辑操作符

XY Y跟在X后面
X|Y X或Y
(X) 捕获组

5.量词

贪婪型 勉强型 占有型 如何匹配
X? X?? X?+ 一个或零个X
X* X*? X*+ 零个或多个X
X+ X+? X++ 一个或多个X
X{n} X{n}? X{n}+ 恰好n次X
X{n,} X{n,}? X{n,}+ 至少n次X
X{n,m} X{n,m}? X{n,m}+ X至少n次,且不超过m次

二、Pattern类

1.Pattern类的实例获取—compile方法

1.下面主要是Pattern类源码下一些重要的方法


private Pattern(String p, int f) {
    pattern = p;
    flags = f;

    // to use UNICODE_CASE if UNICODE_CHARACTER_CLASS present
    if ((flags & UNICODE_CHARACTER_CLASS) != 0)
        flags |= UNICODE_CASE;

    // Reset group index count
    capturingGroupCount = 1;
    localCount = 0;

    if (!pattern.isEmpty()) {
        try {
            compile();
        } catch (StackOverflowError soe) {
            throw error("Stack overflow during pattern compilation");
        }
    } else {
        root = new Start(lastAccept);
        matchRoot = lastAccept;
    }
}

从Pattern类代码可以看出构造器是私有的,故无法使用new去获得Pattern类对象实例。

仔细查询Pattern类下代码后发现通过静态方法compile去获取Pattern类的实例对象。


public static Pattern compile(String regex) {
    return new Pattern(regex, 0);
}

通过compile方法生成一个Pattern类实例对象,然后将想要匹配的字段传入Pattern对象的matcher()方法,matcher()方法会返回生成一个Matcher类实例对象,这个对象也有很多对应的方法。所以Matcher类也是无法通过new去创建一个实例的,而是通过matcher方法


public Matcher matcher(CharSequence input) {
    if (!compiled) {
        synchronized(this) {
            if (!compiled)
                compile();
        }
    }
    Matcher m = new Matcher(this, input);
    return m;
}

public static boolean matches(String regex, CharSequence input) {
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    return m.matches();
}

所以之前博客开头那个问题,也可以用另外两种方式实现:

方式一:


Pattern len = Pattern.compile("^[A-Z].*[\\.]$");
Matcher matcher = len.matcher("Taaa.");
boolean matches = matcher.matches();
System.out.println(matches);

当是从源码中可以看出matches方法是类静态方法,所以没必要使用Macher类实例对象来调用方法。可以使用:

方式二:


System.out.println(Pattern.matches("^[A-Z].*[\\.]$","Taaa."));

2.split方法

下面是Split方法的源码:


public String[] split(CharSequence input, int limit) {
    int index = 0;
    boolean matchLimited = limit > 0;
    ArrayList<String> matchList = new ArrayList<>();
    Matcher m = matcher(input);

    // Add segments before each match found
    while(m.find()) {
        if (!matchLimited || matchList.size() < limit - 1) {
            if (index == 0 && index == m.start() && m.start() == m.end()) {
                // no empty leading substring included for zero-width match
                // at the beginning of the input char sequence.
                continue;
            }
            String match = input.subSequence(index, m.start()).toString();
            matchList.add(match);
            index = m.end();
        } else if (matchList.size() == limit - 1) { // last one
            String match = input.subSequence(index,
                                             input.length()).toString();
            matchList.add(match);
            index = m.end();
        }
    }

    // If no match was found, return this
    if (index == 0)
        return new String[] {input.toString()};

    // Add remaining segment
    if (!matchLimited || matchList.size() < limit)
        matchList.add(input.subSequence(index, input.length()).toString());

    // Construct result
    int resultSize = matchList.size();
    if (limit == 0)
        while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
            resultSize--;
    String[] result = new String[resultSize];
    return matchList.subList(0, resultSize).toArray(result);
}

方法解析:

input:要拆分的字符序列;

limit:结果阈值;根据指定模式拆分输入序列。

limit参数作用:

limit参数控制应用模式的次数,从而影响结果数组的长度。

如果 n 大于零,那么模式至多应用 n- 1 次,数组的长度不大于 n,并且数组的最后条目将包含除最后的匹配定界符之外的所有输入。

如果 n 非正,那么将应用模式的次数不受限制,并且数组可以为任意长度。

如果 n 为零,那么应用模式的次数不受限制,数组可以为任意长度,并且将丢弃尾部空字符串。

详细讲解:假设 input=“boo:and:foo”,匹配符为"o",可知模式最多可应用4次,数组的长度最大为5;

1、当limit=-2时,应用模式的次数不受限制且数组可以为任意长度;推测模式应用4次,数组的长度为5,数组为{“b”,"",":and:f","",""};

2、当limit=2时,模式至多应用1次,数组的长度不大于 2,且第二个元素包含除最后的匹配定界符之外的所有输入;推测模式应用1次,数组的长度为2,数组为{“b”,“o:and:foo”};

3、当limit=7时,模式至多应用6次,数组的长度不大于 7;推测模式应用4次,数组的长度为5,数组为{“b”,"",":and:f","",""};

4、当limit=0时,应用模式的次数不受限制,数组可以为任意长度,并且将丢弃尾部空字符串;推测模式应用4次,数组的长度为3,数组为{“b”,"",":and:f"}。

这里m.find像迭代器,遍历输入字符串

3.Pattern中匹配标记参数

编译标记 效果
Pattern.CANON_EQ 启用规范等价。当且仅当两个字符的“正规分解(canonicaldecomposition)”都完全相同的情况下,才认定匹配。默认情况下,不考虑“规范相等性(canonical equivalence)”。
Pattern.CASE_INSENSITIVE 启用不区分大小写的匹配。默认情况下,大小写不敏感的匹配只适用于US-ASCII字符集。这个标志能让表达式忽略大小写进行匹配,要想对Unicode字符进行大小不敏感的匹配,只要将UNICODE_CASE与这个标志合起来就行了。
Pattern.COMMENTS 模式中允许空白和注释。在这种模式下,匹配时会忽略(正则表达式里的)空格字符(不是指表达式里的“\s”,而是指表达式里的空格,tab,回车之类)。注释从#开始,一直到这行结束。可以通过嵌入式的标志来启用Unix行模式。
Pattern.DOTALL 启用dotall模式。在这种模式下,表达式‘.'可以匹配任意字符,包括表示一行的结束符。默认情况下,表达式‘.'不匹配行的结束符。
Pattern.MULTILINE 启用多行模式。在这种模式下,‘^'和‘ ' 分 别 匹 配 一 行 的 开 始 和 结 束 。 此 外 , ‘ ' 仍 然 匹 配 字 符 串 的 开 始 , ‘ '分别匹配一行的开始和结束。此外,‘^'仍然匹配字符串的开始,‘ '分别匹配一行的开始和结束。此外,‘'仍然匹配字符串的开始,‘'也匹配字符串的结束。默认情况下,这两个表达式仅仅匹配字符串的开始和结束。
Pattern.UNICODE_CASE 启用Unicode感知的大小写折叠。在这个模式下,如果你还启用了CASE_INSENSITIVE标志,那么它会对Unicode字符进行大小写不敏感的匹配。默认情况下,大小写不敏感的匹配只适用于US-ASCII字符集。
Pattern.UNIX_LINES 启用Unix行模式。在这个模式下,只有‘\n'才被认作一行的中止,并且与‘.'、‘^'、以及‘$'进行匹配。

Pattern.CASE_INSENSITIVEPattern.COMMENTSPattern.MULTILINE这三个比较常用。

三、Matcher类

对照Matcher构造器源码,可知构造器将Pattern对象的引用赋于Matcher中变量parentPattern,目标字符串赋于变量text;并创建了数组groups和locals 。

数组groups是组使用的存储。存储的是当前匹配的各捕获组的first和last信息。

groups[0]存储的是组零的first,groups[1]存储的是组零的last,groups[2]存储的是组1的first,groups[3]存储的是组1的last,依次类推。

Matcher类的方法非常多,这里就不对每个方法的源码进行详细的解读了,后续如果有空会深入研究一下。将常用方法总结如下

方法名 功能作用
public int groupCount() 返回此匹配器中的捕获组数
public String group() 实际上是调用了group(int group) ,只不过参数是0
public String group(int group) 返回当前查找而获得的与组匹配的所有子串内容
public int start() 返回当前匹配的子串的第一个字符在目标字符串中的索引位置
public int start(int group) 返回当前匹配的指定组中的子串的第一个字符在目标字符串中的索引位置 。
public int end() 返回当前匹配的子串的最后一个字符的下一个位置在目标字符串中的索引位置 。
public int end(int group) 返回当前匹配的的指定组中的子串的最后一个字符的下一个位置在目标字符串中的索引位置
public boolean find() 在目标字符串里查找下一个匹配子串
public boolean find(int start) 重置此匹配器,然后尝试查找匹配该模式,从指定的位置开始查找下一个匹配的子串
public int regionStart() 报告此匹配器区域的开始索引。
public int regionEnd() 报告此匹配器区域的结束索引(不包括)。
public Matcher region(int start,int end) 设置此匹配器的区域限制。重置匹配器,然后设置区域,使其从start参数指定的索引开始,到 end参数指定的索引结束(不包括end索引处的字符)。
public boolean lookingAt() 从目标字符串开始位置进行匹配。只有在有匹配且匹配的某一子串中包含目标字符串第一个字符的情况下才会返回true。
public boolean matches() 只有完全匹配时才会返回true。
public Matcher appendReplacement(StringBuffer sb, String replacement) 将当前匹配子串替换为指定字符串,并将从上次匹配结束后到本次匹配结束后之间的字符串添加到一个StringBuffer对象中,最后返回其字符串表示形式。
public StringBuffer appendTail(StringBuffer sb) 将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。
public String replaceAll(String replacement) 将匹配的子串用指定的字符串替换。
public String replaceFirst(String replacement) 将匹配的第一个子串用指定的字符串替换。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Java字符串 正则表达式详解

本文链接: https://www.lsjlt.com/news/135007.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java字符串 正则表达式详解
    目录一、规则表1.字符2.字符类 .3.边界匹配符4.逻辑操作符5.量词二、Pattern类1.Pattern类的实例获取—compile方法2.split方法3.Pattern中匹...
    99+
    2022-11-12
  • C#字符串与正则表达式的图文详解
    1.创建字符串 string 变量名 = "字符串内容";            string str = "abcdrf";             Conso...
    99+
    2022-11-13
  • 正则表达式之字符串模式匹配实例详解
    目录前言什么是正则表达式字符范围匹配元字符多次重复匹配定位匹配贪婪模式与非贪婪模式表达式分组结语前言 今天我们来学习正则表达式,正则表达式的应用十分广泛,几乎每个涉及到交互的项目都会...
    99+
    2022-11-13
  • Python字符串与正则表达式详细介绍
    目录一、字符串相关操作 二、正则表达式相关操作一、字符串相关操作  1.统计所输入字符串中单词的个数,单词之间用空格分隔。其运行效果如下图所示。 s=input(...
    99+
    2022-11-13
  • Java正则表达式循环匹配字符串方式
    目录正则表达式循环匹配字符串Java匹配正则表达式大全我们先举个例子来看看Java匹配正则表达式匹配表达式的特殊情况正则表达式循环匹配字符串 public static void m...
    99+
    2022-11-13
  • Java正则表达式API字符类
    目录一、Predefined字符类二、Quantifiers三、Capturing Groups一、Predefined字符类 Java正则表达式API也接受预定义的字符类。上面的一...
    99+
    2022-11-13
  • mysql字符串正则表达式及说明
    目录概述正则表达式运算符正则表达式语法概述 名称描述NOT REGEXP否定的REGEXPREGEXP字符串是否匹配正则表达式RLIKE字符串是否匹配正则表达式 正则表达式是指定复杂...
    99+
    2022-11-13
  • Java 正则表达式详解
    正则表达式(Regular Expression),又称为正规表达式、规则表达式、常规表示法等,是一种用来匹配、查找和替换字符串的工...
    99+
    2023-08-16
    Java
  • java学习指南之字符串与正则表达式
    目录String构造方法格式控制字符串常用方法StringBuilder与StringBuffer特点理解可变与不可变字符串拼接方法字符串删除方法字符串内插入字符字符串替换方法字符串...
    99+
    2023-05-18
    java 字符串正则 java中正则表达式 java字符串与正则表达式
  • 怎么使用java正则表达式获取字符串
    要使用Java正则表达式获取字符串,可以按照以下步骤进行操作:1. 导入`java.util.regex`包。在Java中,正则表达...
    99+
    2023-09-05
    java
  • java 判断字符串中有汉字 (常用正则表达式)
    今天在开发中碰到了判断字符串中是否有汉字的问题,方便起见,记录下来以便后期查看。 通过正则表达式判断 判断汉字 String address = "北京市朝阳区阜通东大街6号";String lonAndLat = "";Pattern p...
    99+
    2023-09-14
    正则表达式 java
  • 正则表达式不包含特定字符串
    要实现一个正则表达式不包含特定字符串的模式,可以使用“负向预查”来实现。负向预查是一种零宽度断言,可以在匹配之前或之后断言某个位置不...
    99+
    2023-08-18
    正则表达式
  • python利用正则表达式提取字符串
    前言 正则表达式的基础知识就不说了,有兴趣的可以点击这里,提取一般分两种情况,一种是提取在文本中提取单个位置的字符串,另一种是提取连续多个位置的字符串。日志分析会遇到这种情况,下面我会分别讲一下对应的方法。...
    99+
    2022-06-04
    字符串 正则表达式 python
  • Python正则表达式匹配字符串中的数字
    这篇文章主要介绍了Python正则表达式匹配字符串中的数字,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下1.使用“\d+”匹配全数字...
    99+
    2023-06-01
  • 如何根据正则表达式生成字符串
    根据正则表达式生成字符串可以使用以下方法:1. 生成随机字符串:使用Python的`random`模块生成随机字符,并根据正则表达式...
    99+
    2023-09-28
    正则表达式
  • 正则表达式不包含特定字符串吗
    正则表达式是一种用于匹配字符串模式的工具,可以用来检查一个字符串是否包含特定的子字符串。在正则表达式中,可以使用一些特殊的元字符和语...
    99+
    2023-08-21
    正则表达式
  • python怎么用正则表达式提取字符串
    今天小编给大家分享一下python怎么用正则表达式提取字符串的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。用正则表达式提取字...
    99+
    2023-07-05
  • python如何用正则表达式提取字符串
    目录用正则表达式提取字符串1. 单个位置的字符串提取2. 连续多个位置的字符串提取用正则表达式提取字符串中的整数总结用正则表达式提取字符串 在日常工作中经常遇见在文本中提取特定位置字...
    99+
    2023-03-02
    python正则表达式 python提取字符串 正则提取字符串
  • Java如何使用正则表达式查找指定字符串
    对于一个文件名的使用经常要做一些判断,比如文件名是否是指定的名字,或者文件是否为指定的类型,或者筛选出以指定后缀结尾的文件名,等等 这时就可以提取出文件名的字符串进行比较判断筛选 在...
    99+
    2022-11-13
  • java利用正则表达式如何实现查找字符串
    java利用正则表达式如何实现查找字符串?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。具体如下:Hello.java:package hello;import ...
    99+
    2023-05-31
    java 正则表达式 字符串
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作