JAVA正则表达式

正则表达式示例

查找字符串 http://是否出现。

import java.util.regex.Pattern;
public class RegexText {
    public static void main(String[] args) {
        String text    =
                "This is the text to be searched " +
                        "for occurrences of the http:// pattern.";
        String pattern = ".*http://.*";
        boolean matches = Pattern.matches(pattern, text);
        System.out.println("matches = " + matches);
        //matches = true
    }
}

正则表达式的API

Pattern (java.util.regex.Pattern)

Pattern.matches()

检查一个正则表达式的模式是否匹配一段文本的最直接方法是调用静态方法Pattern.matches()

Pattern.compile()
如果需要匹配多次出现,需要通过Pattern.compile() 方法得到一个Pattern实例。

        String text    =
                "This is the text to be searched " +
                        "for occurrences of the http:// pattern.";
        String patternString = ".*http://.*";
//        Pattern pattern = Pattern.compile(patternString);
//        可以在Compile 方法中,指定一个特殊标志:下面是忽略大小写
        Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
        //public static final int CASE_INSENSITIVE = 0x02;

Pattern.matcher()一个r结尾 一个s结尾

一旦获得了Pattern对象,接着可以获得Matcher对象。Matcher类有很多方法其中一个matches()方法,可以检查文本是否匹配模式.示例如下

String text    =
        "This is the text to be searched " +
        "for occurrences of the http:// pattern.";
String patternString = ".*http://.*";
Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
boolean matches = matcher.matches();
System.out.println("matches = " + matches);

Pattern.split()
Pattern 类的 split()方法,可以用正则表达式作为分隔符,把文本分割为String类型的数组。

import java.util.regex.Pattern;
public class RegexText {
    public static void main(String[] args) {
        String text = "A sep Text sep With sep Many sep Separators";
        String patternString = "sep";
        Pattern pattern = Pattern.compile(patternString);
        String[] split = pattern.split(text);
        System.out.println("split.length = " + split.length);
        for(String element : split){
            System.out.println("element = " + element);
        }
        /*
        split.length = 5
        element = A 
        element =  Text 
        element =  With 
        element =  Many 
        element =  Separators
         */
    }
}

Pattern.pattern()
Pattern 类的 pattern 返回用于创建Pattern 对象的正则表达式,示例:

 String patternString = "sep";
Pattern pattern = Pattern.compile(patternString);
String pattern2 = pattern.pattern();
System.out.println(pattern2);//sep
//上面代码中 pattern2 值为sep ,与patternString 变量相同。

Matcher (java.util.regex.Matcher)

用于匹配一段文本中多次出现一个正则表达式
多文本中匹配同一个正则表达式

创建Matcher
通过Pattern 的matcher() 方法创建一个Matcher。

matcher.matches()
返回布尔值 是否有匹配到

matcher.lookingAt()
开头匹配正则表达式换句话说是否以正则表达式开头

String text    =
                "This is the text to be searched " +
                        "for occurrences of the http:// pattern.";
String patternString = ".his is the";
Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
System.out.println("lookingAt = " + matcher.lookingAt());
System.out.println("matches   = " + matcher.matches());
//        lookingAt = true
//        matches   = false  它要求前后不能有多余字符 patternString后面不准匹配

matcher.find() + matcher.start() + matcher.end()
find() 方法用于在文本中查找出现的正则表达式
find()方法返回第一个,之后每次调用 find()都会返回下一个。
start()end()返回每次匹配的字串在整个文本中的开始和结束位置。实际上,end()返回的是字符串末尾的后一位,这样,可以在把start()end()的返回值直接用在String.substring()

String text    =
        "This is the text which is to be searched " +
                "for occurrences of the word 'is'.";
String patternString = "is";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
int count = 0;
while(matcher.find()) {
    count++;
    System.out.println("found: " + count + " : "  + matcher.start() + " - " + matcher.end());
}
//        found: 1 : 2 - 4
//        found: 2 : 5 - 7
//        found: 3 : 23 - 25
//        found: 4 : 70 - 72

matcher.reset()
reset() 方法会重置Matcher内部的 匹配状态。当find()方法开始匹配时,Matcher 内部会记录截至当前查找的距离。调用 reset()会重新从文本开头查找
matcher.group()多分组
(John)
此正则表达式匹配John, 括号不属于要匹配的文本。括号定义了一个分组。当正则表达式匹配到文本后,可以访问分组内的部分。
(John) (.+?)
这个表达式匹配文本”John” 后跟一个空格,然后跟1个或多个字符,最后跟一个空格。你可能看不到最后的空格。
字符 点 . 表示任意字符。 字符 + 表示出现一个或多个,和. 在一起表示 任何字符,出现一次或多次。字符? 表示 匹配尽可能短的文本。

String text    =
        "John writes about this, and John Doe writes about that," +
                " and John Wayne writes about everything."
        ;
String patternString1 = "(John) (.+?) ";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);
while(matcher.find()) {
    System.out.println("found: " + matcher.group(1) +
            " "       + matcher.group(2));
}
//        found: John writes
//        found: John Doe
//        found: John Wayne

matcher.group()嵌套分组
((John) (.+?))
当遇到嵌套分组时, 分组编号是由左括号的顺序确定的。上例中,分组1 是那个大分组。分组2 是包括John的分组,分组3 是包括 .+? 的分组。

String text    =
        "John writes about this, and John Doe writes about that," +
                " and John Wayne writes about everything."
        ;
String patternString1 = "((John) (.+?)) ";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);
while(matcher.find()) {
    System.out.println("found:   "+matcher.group(1));
}
//        found:   John writes
//        found:   John Doe
//        found:   John Wayne

matcher.replaceAll() + matcher.replaceFirst()
replaceAll()replaceFirst()方法可以用于替换Matcher搜索字符串中的一部分。replaceAll()方法替换全部匹配的正则表达式,replaceFirst()只替换第一个匹配的。

String text    =
        "John writes about this, and John Doe writes about that," +
                " and John Wayne writes about everything."
        ;
String patternString1 = "((John) (.+?)) ";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);

String replaceAll = matcher.replaceAll("Joe Blocks ");
System.out.println("replaceAll   = " + replaceAll);
//        replaceAll   = Joe Blocks about this, and Joe Blocks writes about that, and Joe Blocks writes about everything.
String replaceFirst = matcher.replaceFirst("Joe Blocks ");
System.out.println("replaceFirst = " + replaceFirst);
//        replaceFirst = Joe Blocks about this, and John Doe writes about that, and John Wayne writes about everything.

matcher.appendReplacement() + matcher.appendTail()
appendReplacement()appendTail() 方法用于替换输入文本中的字符串短语,同时把替换后的字符串附加到一个 StringBuffer 中。

find()方法找到一个匹配项时,可以调用 appendReplacement() 方法,这会导致输入字符串被增加到StringBuffer 中,而且匹配文本被替换。 从上一个匹配文本结尾处开始,直到本次匹配文本会被拷贝。

appendReplacement()会记录拷贝StringBuffer 中的内容,可以持续调用find(),直到没有匹配项。

直到最后一个匹配项目,输入文本中剩余一部分没有拷贝到StringBuffer. 这部分文本是从最后一个匹配项结尾,到文本末尾部分。通过调用 appendTail() 方法,可以把这部分内容拷贝到 StringBuffer 中.

String text    =
        "John writes about this, and John Doe writes about that," +
                " and John Wayne writes about everything."
        ;

String patternString1 = "((John) (.+?)) ";
Pattern pattern = Pattern.compile(patternString1);
Matcher  matcher = pattern.matcher(text);
StringBuffer stringBuffer = new StringBuffer();

while(matcher.find()){
    matcher.appendReplacement(stringBuffer, "Joe Blocks ");
    System.out.println(stringBuffer.toString());
}
matcher.appendTail(stringBuffer);
System.out.println(stringBuffer.toString());
//Joe Blocks
//Joe Blocks about this, and Joe Blocks
//Joe Blocks about this, and Joe Blocks writes about that, and Joe Blocks
//Joe Blocks about this, and Joe Blocks writes about that, and Joe Blocks writes about everything.

Java 正则表达式语法

字符
支持8进制,16进制或unicode编码

101
\x41
\u0041

以上3个表达式 都表示大写字符A
[abc]想匹配字符 a,b 或c
\d表示任意数字
\s 表示任意空白字符
\w 表示任意单词字符
^匹配行首
$ 匹配行尾
A* 字母A 出现0次或多次
A+ 表示1次或多次
A? 表示0次或1次
John went for a walk, and John fell down, and John hurt his knee.
John.*?
. 表示任意字符。* 表示0或多次。? 跟在 * 后面,表示 * 采用饥饿模式。
饥饿模式下,量词只会匹配尽可能少的字符,即0个字符。
John.*+hurt
*后跟+ 表示独占模式
这个表达式在输入文本中没有匹配项,尽管文本中包括 John 和 hurt. 为什么会这样? 因为.* + 是独占模式。与贪婪模式下,尽可能多的匹配文本,以使整个表达式匹配不同。独占模式会尽可能的多的匹配,但不考虑表达式剩余部分是否能匹配上改成John.*hurt会有一个匹配项

. 任意英文字母
\ 反斜杠, 单独的反斜杠做为转义字符,与其他特殊字符一起使用。如果想匹配反斜杠本身,需要转义。两个反斜杠实际匹配一个反斜杠n字符的8进制表示.n 在0至7之间取值
nn 字符的8进制表示.n 在0至7之间取值
mnn 字符的8进制表示. m 在0至3之间取值, n 在0至7之间取值
\xhh 字符的16进制表示.
\uhhhh 字符的16进制表示 0xhhhh. 对应unicode 编码字符
\t 缩进符.
\n 换行符 (unicode: ‘\u000A’)
\r 回车符 (unicode: ‘\u000D’)
\f 制表符 (unicode: ‘\u000C’)
\a 警报(铃声)字符 (unicode: ‘\u0007′)
\e 转义符 (unicode: ‘\u001B’)
\cx 控制符 x

字符分类

[abc] 匹配 a, 或 b 或 c
[^abc] 匹配不是a,b,c 的字符,是否定匹配
[a-zA-Z] 匹配a 到 z ,A到Z 直接的字符,是范围匹配
[a-d[m-p]] 匹配a到d之间字符或 m到p之间字符,是并集匹配
[a-z&&[def]] 匹配 d, e, 或 f. 是交集匹配 (这里是在范围 a-z和字符def之间取交集).
[a-z&&[^bc]] 匹配a-z 之间所有字符,排除bc的字符。是减法匹配
[a-z&&[^m-p]] 匹配a-z 之间所有字符,排除m-p之间的字符是减法匹配

内置字符分类

. 匹配任意一个字符,根据创建Pattern是传入的标志,可能匹配行结尾符
\d 匹配任意数字 [0-9]
\D 匹配任意非数字 [^0-9]
\s 匹配任意空白符 (空格, 缩进, 换行,回车)
\S 匹配任意非空白符
\w 匹配任意单词
\W 匹配任意非单词

边界匹配

^ 匹配行首
$ 匹配行尾
\b 匹配单词边界
\B 匹配非单词边界
\A 匹配文本开头
\G 匹配前一匹配项结尾
\Z Matches the end of the input text except the final terminator if any
\z 匹配文本结尾

量词


参考出处:https://juejin.im/entry/572980421ea493006064433c

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容