RegEx入门杂乱笔记

匹配URL地址

匹配目多级子目录以及可选的args

匹配目标地址或者主机名以及可选的port

匹配协议名以及可选的username:password

虽然Java不支持嵌入条件,但想要匹配美国邮政编码的话可以使用\b\d{5}(-\d{4})?(?!-)\b

Java的RegEx不支持嵌入条件也不支持POSIX元字符类

正则表达式 想匹配出需要的内容很容易实现,但是要求其不能匹配出我们不需要的内容(即精确匹配)却很困难

Intellij IDEA也不支持嵌入条件
Java不支持嵌入条件
精确匹配邮箱地址

除了正前后查找还有,负前后查找,他们的操作符分别是
(?!)(?<!)规则类似

\b(?<!$)\d+\b
\b(?<=$)\d+\b

EaEb表达式,前者匹配长度可以是任意的
后者则必须是固定的,不能出现诸如* + {2,} 类似的表达式
否则如果使用的是Java RegEx的话,将抛出
Exception in thread "main" java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index XX
但如果如果是集合或者单个字符,却可以配合使用如
(?<=[a-z]*) (?<=\d*) (?<=\w+) (?<=f*)
但这些是非法的
(?<=a\w*) (?<=k\d*) (?<=\w\w+) (?<=aa+)
换句话说,如果(positive lookahead)要匹配不固定长,那么只能是单个集合
(?<=[afgvds]{2,}) 这也是一个合法的向后查找

(?=Ea)为向前查找,在一个表达式的尾部
(?<=Eb)为向后查找,在一个表达式的尾部

Java即支持正向前查找(positive lookahead) ,也支持正向后查找(positive lookbehind),他们是对某一位置的前后进行查找,但它们并不是匹配结果的一部分。

Java RegEx不支持 \U \u \L \l \E这样的元字符
但是Intellj IDEA支持

还原操作

RegEx Replace
\((\d{3})\) (\d{3}-\d{4}) $1-$2

替换操作

RegEx Replace
(\d{3})-(\d{3})(-)(\d{4}) ($1) $2-$4
(\d{3})-(\d{3}-)(\d{4}) ($1) $2$3 (而不是 ($1) $2-$3 必须要跨度大于1时,-才被转义)
(\d{3})-(\d{3}-\d{4}) ($1) $2
(?<header>\d{3})-(?<tail>\d{3}-\d{4}) (${header}) ${tail}
替换前 替换后
494-939-5505 (494) 939-5505
427-836-2491 (427) 836-2491
142-620-0294 (142) 620-0294
246-767-4276 (246) 767-4276
585-328-1029 (585) 328-1029

子表达式可用来进行回溯引用匹配,用\1,\2,...\n来分别代表第n个表达式
但如果子表达式的相对位置发生了变化,整个模式也许就不能再完成原来的工作,删除或添加子表达式的后果可能更为严重。
所以,一些比较新的正则表达式实现还支持命名捕获:给某个子表达式起一个唯一的名字,然后用这个名字(而不是相对位置)来引用这个子表达式.

Java RegEx 支持命名捕获,可混合使用编号和命名来引用前面子表达式的内容

     public static void main(String[] args) {
        String input = "<BODY>\n" +
                "<H1>Welcome to my Homepage</H1>\n" +
                "Content is divided into two sections:<BR>\n" +
                "<H2>ColdFusion</H2> <h2>ColdFusion</h2> <H3>Wireless</H5>\n" +
                "Information about Macromedia ColdFusion.\n" +
                "<H3>Wireless</H3>\n" +
                "<H3>Wireless</h3>\n" +
                "Information about Bluetooth, 802.11, and more.\n" +
                "</BODY>";//<(?<x>[Hh])(?<y>[1-6]).*?\1\k<y>>
        Pattern pattern = Pattern.compile("<(?<x>[Hh])(?<y>[1-6]).*?\\1\\k<y>>");
        Matcher matcher = pattern.matcher(input);
        System.out.println(pattern.pattern());
        while (matcher.find()) {
            System.out.println(matcher.group(0));//等价matcher.group()
            System.out.println(matcher.group(1));//回溯引用第一个子表达式匹配到的内容
            System.out.println(matcher.group(2));//回溯引用第二个子表达式匹配到的内容
            System.out.println(matcher.group("x"));//采用命名捕获,回溯引用第一个子表达式匹配到的内容
            System.out.println(matcher.group("y"));//采用命名捕获,回溯引用第二个子表达式匹配到的内容
        }
        System.out.println(matcher.toMatchResult().groupCount());//返回子表达式的个数
    }

匹配1个字节能表达的范围0-255,使用
正则表达式\b(2[0-4]\d|25[0-5]|1?\d{1,2})\b
而不是\b(1?\d{1,2}|2[0-4]\d|25[0-5])\b
假如使用(1?\d{1,2}|2[0-4]\d|25[0-5])匹配255时候,将匹配255
而使用(1?\d{1,2}|2[0-4]\d|25[0-5])\.匹配255.时候,将匹配255.而不是55.
但要匹配55.,则使用\B(1?\d{1,2}|2[0-4]\d|25[0-5])\.

\b((2[0-4]\d|25[0-5]|1?\d{1,2}).){3}(2[0-4]\d|25[0-5]|1?\d{1,2})\b

如果使用了(?m)的多行模式匹配,那么^将匹配\n的结束位置,
$将匹配\n的开始位置

Intellij IDEA默认使用多行模式匹配

Java RegEx支持使用?(m)进行多行模式匹配

[\s\S]将匹配任意字符类似的都具有该功能如[\w\W],[\d\D]

(.|\n)也可以真正的匹配任意字符

        input = " a\n" +
                " /** this is a test \n" +
                "code \n" +
                "wo fas ga hdh sha\n" +
                "end?\n" +
                "*/*/\n" +
                "*/";//(?m)^\s*/\*[\S\s]*?\*/

        Pattern pattern = Pattern.compile("(?m)^\\s*/\\*[\\S\\s]*?\\*/");

        Matcher matcher = pattern.matcher(input);
        while (matcher.find()) 
            System.out.println("[" + matcher.start() + ",\n" 
            + matcher.group() 
            + "\n," + matcher.end() + "]");
        
输出结果:
[3,
 /** this is a test 
code 
wo fas ga hdh sha
end?
*/
,55]

^.*$可以匹配任意的非空字符串
\<\>也用来匹配单词边界,前者匹配单词开头,后者匹配单词结尾,
但是Java提供的正则表达式和Intellij IDEA都不支持,egrep程序支持

位置匹配元字符 功能描述
\b 不匹配任何字符,匹配\w\W之间的位置
\B 不匹配任何字符,匹配\w\w\W\W之间的位置

匹配连线符

string regex
nine-digit \b-\b
nine- digit \b-\B
nine - digit \B-\B
nine -digit \B-\b

\b匹配且只匹配一个位置,不匹配任何字符。用\bcat\b
匹配到的字符串的长度是3个字符(c,a,t),不是5个字符。

贪婪型元字符 懒惰型元字符
* *?
+ +?
{m,} {m,}?
{m,n} {m,n}?

对于下面的那种情况,使用<[Bb]>.{1,16}</[Bb]>也会导致过度匹配.

<[Bb]>.*?</[Bb]使用*的懒惰版,加上?即可
<[Bb]>.*</[Bb]> 过度匹配

M{X(,Y)} ,Y是可选的
0=<X<=Y
表示前面的M模式将出现至少X次,至多Y

?是一个元字符,如果要匹配?本身,就必须使用它的转义序列\?
该元字符的功能是匹配0个或1个字符
\*是一个元字符,如果要匹配*本身,就必须使用它的转义序列\\*
该元字符的功能是匹配0个或多个字符

\d+: $\d{3,}.\d{2}
#[0-9a-fA-F]{6}
\d{1,2}[-/]\d{1,2}[-/]\d{2,4}

[\r]?\n用来兼容在window和linux/unix上的换行符兼容

该正则表达式并不完善,最后的那个错误邮箱也会被匹配

+是一个元字符,如果要匹配+本身,就必须使用它的转义序列\+
该元字符的功能是匹配一个或多个字符(或字符集合),但至少匹配一个

Java 和 Intellij IDEA 都不支持POSIX字符类`

可以使用16进制或者是8进制来表达正则表达式,但是用这种方式表达出的字符都是普通字符,
[\060\x2d\071]可以翻译为[0-9]但是这个集合只包含0 - 9三个字符,等价于[0\-9]

正则表达式大小写敏感,而且通常对元字符来说大写是小写的取非,如
\w \W 前者等价 [a-zA-Z0-9_],w是 word 的意思,类似还有很多如
\d \D 前者等价 [0-9],d是 digit 的意思

input = "1-8-5-189";//[0-5-9]  匹配不到8,正则表达式采用的贪心的方式0-5集合- 和9 组成的集合

Pattern pattern = Pattern.compile("[0-5-9]");

Matcher matcher = pattern.matcher(input);

var myArray = new Array();
...
if (myArray[0] == 0) {
...
}
if (myArray[1] == 0) {
...
}
if (myArray[2] == 0) {
...
}
if (myArray[3] == 0) {
...
}
matches here using regex: if (myArray[[0-9]] == 0) {\n...\n}
任何的一个元字符如果想要匹配其本身,都可以通过加上一个反斜杠做为其前缀的办法。


.和[类原始就是元字符, t和n类必须转义后才算是元字符

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

/**
 * Created by E on 2017/8/1.
 */
@SuppressWarnings("UnusedAssignment")
public class _01 {
    //以下测试的正则表达式都适用于java语言中的字符串表达的正则表达式
    public static void main(String[] args) {
        String input;
        input = " car scar CAR Car CaR carry incarerate car carcar";//[Cc][Aa][Rr] 匹配所有car忽略大小写
        input = "Hello, my name is Ben. Please visit my website at http://www.forta.com/.ben";//纯文本匹配
        String s = "sales1.xls " +
                "orders3.xls" +
                " sales2.xls" +
                " sales3.xls" +
                " apac1.xls" +
                " europe2.xls" +
                " na1.xls" +
                " na2.xls" +
                " sa1.xls ";//.a.\\.   对于后面的\\对应一个java转义为一个反斜杠,然后\.告诉正则表达式这不是一个模式,纯文本
        input = s;

        input = "\\ 123.";//\\\\ java转义为两个\\,正则表达式转义成1个杠,然后匹配 字符串里面的一个杠杠\

        input = "a\n";//a.无法匹配失败  .匹配任意字符除\n,\转义

        input = "a\n";//a\\n \n匹配换行

        input = s + " usal.xls";//[ns]a.\.xls 元字符使用

        input = "The phrase \"regular expression\" is often\n" +
                "abbreviated as RegEx or regex";//[Rr]eg[Ee]x

        input = "sa2.java sa3.java sa6.java sa4.java sal.java ana3.java";//[ns]a[2-4].ja

        input = "aaaaaaa";//aaa 只会匹配出2个,不会重叠匹配

        input = "[a\\";//\\[a\\   ,  [Z-a]a[Z-a]

        input = "<BODY BGCOLOR=\"#33A6b3\" TEXT=\"#FFfFFF\" MARGINWIDTH=\"0\" MARGINHEIGHT=\"0\" TOPMARGIN=\"0\" LEFTMARGIN=\"0\">";//#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]

        input = "a2 b3 n4 zu qe su nd n8 68 4a t6";//[a-z][^2-4 86]   X-Y,X和Y仅指单个字符对于后面的字符X都将属于这个集合
        //[.]与\.等价,不然如[.af]没有意义af已经被包括在.所描述的集合范围内了,所以将失去他的原本功能

        Pattern pattern = Pattern.compile("");

        Matcher matcher = pattern.matcher(input);
        int count = 0;
        while (matcher.find()) {//输出
            System.out.println("[" + matcher.start() + "," + matcher.group() + "," + matcher.end() + "]");
            count++;
        }
        System.out.println(count);
    }
}

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,590评论 18 139
  • 正则表达式到底是什么东西?字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等...
    狮子挽歌阅读 2,134评论 0 9
  • 注:本篇文章只为方便查看,特此保留,如有冒犯,敬请谅解!!! 本文目标 30分钟内让你明白正则表达式是什么,并对它...
    阿杰Alex阅读 1,475评论 0 10
  • 揭开正则表达式的神秘面纱(转) 关闭高亮 [原创文章,转载请保留或注明出处:http://www.regexlab...
    螃蟹六步郎阅读 317评论 0 0
  • 1. oust 逐出,夺取 He was ousted as a manager. 2. impeachment ...
    Bebevino阅读 88评论 0 0