RegEx入门杂乱笔记

匹配URL地址

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

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

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

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

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

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

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

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

\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
(?
\d{3})-(?\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 = "\n" +
                "

Welcome to my Homepage

\n" + "Content is divided into two sections:
\n" + "

ColdFusion

ColdFusion

Wireless

\n" + "Information about Macromedia ColdFusion.\n" + "

Wireless

\n" + "

Wireless

\n" + "Information about Bluetooth, 802.11, and more.\n" + "";//<(?[Hh])(?[1-6]).*?\1\k> Pattern pattern = Pattern.compile("<(?[Hh])(?[1-6]).*?\\1\\k>"); 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]>.* 过度匹配

M{X(,Y)} ,Y是可选的
0=
表示前面的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 = "";//#[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);
    }
}

你可能感兴趣的:(RegEx入门杂乱笔记)