程序员

浅入深出Re:正则表达式的养成方法

2017-08-31  本文已影响0人  语落心生

以下出自图灵丛书精通正则表达式一书,实验遇到的问题及解决方法,记载在此

Java正则的使用姿势

Regular Expressions API

正则表达式结构 符合匹配条件的内容
. 任何字符
? 前面的0或1个字符或数字
* 前面的零 (0) 或更多个字符或数字
+ 前面的一 (1) 或更多个字符或数字
[ ] 一个字符或数字范围
^ 后面的条件的否定条件(即 “非后面的条件”)
/d 任何数字(也可表示为 [0-9])
/D 任何非数字(也可表示为 [^0-9])
/s 任何空格字符(也可表示为 [\n\t\f\r])
/S 任何非空格字符(也可表示为 [^\n\t\f\r])
\w 任何单词字符(也可表示为 [a-zA-Z_0-9])
\W 任何非单词字符(也可表示为 [^\w])
\b 查找位于单词的开头或结尾的匹配
$ 检查行尾是否如下
(?:pattern) 匹配 pattern 但不捕获该匹配的子表达式

Test1 : 找到一个具有以下形式的字符串:A 或 a 后跟零或多个字符,后跟 string。

 //4nd way
        Pattern pattern = Pattern.compile("[Aa].*string");//匹配string字符串之前的0或者更多字符和数字
        Matcher matcher = pattern.matcher("A string");
        boolean didMatch = matcher.matches();
        System.out.println(didMatch);
        int patternStartIndex = matcher.start();
        System.out.println(patternStartIndex);
        int patternEndIndex = matcher.end();
        System.out.println(patternEndIndex);

每个 Java 语言字符串都是一个带索引的字符集合,索引从 0 开始,到字符串长度减 1 结束。Matcher 从 0 开始解析该字符串,寻找与它匹配的结果。完成处理后,Matcher 包含有关在输入字符串中找到(或未找到)匹配结果的信息。如果字符串中包含的元素比您搜索的模式中字符数要多,可以使用 lookingAt() 代替 matches()。

Test2 : 搜索匹配的较长的字符串信息

matches()

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

/**
 * Created by 26645 on 2017/8/31.
 */
public class RegexTest {
    public static void main(String[] args) {
        Pattern p = Pattern.compile(".s");//表示单个字符
        Matcher m= p.matcher("as");
        boolean b =m.matches();

        //2nd way
        boolean b2 = Pattern.compile(".s").matcher("as").matches();

        //3nd way
        boolean b3 = Pattern.matches(".s","as");

        //4nd way
        Pattern pattern = Pattern.compile("[Aa].*string");//匹配string字符串之前的0或者更多字符和数字
        Scanner scan = new Scanner(System.in);
        if (scan.hasNextLine()){
            Matcher matcher = pattern.matcher(scan.nextLine());
            boolean didMatch = matcher.matches();
            System.out.println(didMatch);
            int patternStartIndex = matcher.start();
            System.out.println(patternStartIndex);
            int patternEndIndex = matcher.end();
            System.out.println(patternEndIndex);
        }
        
    }
}

console output : 字符串中包含比模式中更多的内容,查找失败

false
Exception in thread "main" java.lang.IllegalStateException: No match available
    at java.util.regex.Matcher.start(Matcher.java:343)
    at RegexTest.main(RegexTest.java:28)

lookingAt()

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

/**
 * Created by 26645 on 2017/8/31.
 */
public class RegexTest {
    public static void main(String[] args) {
        Pattern p = Pattern.compile(".s");//表示单个字符
        Matcher m= p.matcher("as");
        boolean b =m.matches();

        //2nd way
        boolean b2 = Pattern.compile(".s").matcher("as").matches();

        //3nd way
        boolean b3 = Pattern.matches(".s","as");

        //4nd way
        Pattern pattern = Pattern.compile("[Aa].*string");//匹配string字符串之前的0或者更多字符和数字
        Scanner scan = new Scanner(System.in);
        if (scan.hasNextLine()){
            Matcher matcher = pattern.matcher(scan.nextLine());
            boolean didLookingAt = matcher.lookingAt();
            //boolean didMatch = matcher.matches();
            System.out.println(didLookingAt);
            int patternStartIndex = matcher.start();
            System.out.println(patternStartIndex);
            int patternEndIndex = matcher.end();
            System.out.println(patternEndIndex);
        }

    }
}

console output:匹配失败,lookingAt()方法只匹配正则表达式与文本的开头。

false
Exception in thread "main" java.lang.IllegalStateException: No match available
    at java.util.regex.Matcher.start(Matcher.java:343)
    at RegexTest.main(RegexTest.java:28)

那么如果我们想要在模式匹配中找到非0索引开头的字符串,我们应该怎么做呢?
Bingo! find() 方法,stackoverflow提议传送门

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

/**
 * Created by 26645 on 2017/8/31.
 */
public class RegexTest {
    public static void main(String[] args) {
        Pattern p = Pattern.compile(".s");//表示单个字符
        Matcher m= p.matcher("as");
        boolean b =m.matches();

        //2nd way
        boolean b2 = Pattern.compile(".s").matcher("as").matches();

        //3nd way
        boolean b3 = Pattern.matches(".s","as");

        //4nd way
        Pattern pattern = Pattern.compile("[Aa].*string");//匹配string字符串之前的0或者更多字符和数字
        Scanner scan = new Scanner(System.in);
        String str1="7-11";
        String regex = "-";
        Pattern ptest = Pattern.compile(regex);
        Matcher m1 = ptest.matcher(str1);
        System.out.println(m1.lookingAt());

        if (scan.hasNextLine()){
            Matcher matcher = pattern.matcher(scan.nextLine());
            //boolean didLookingAt = matcher.lookingAt();
            //boolean didMatch = matcher.matches();
            boolean didfind = matcher.find();
            System.out.println(didfind);
            int patternStartIndex = matcher.start();
            System.out.println(patternStartIndex);
            int patternEndIndex = matcher.end();
            System.out.println(patternEndIndex);
        }

    }
}

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=61963:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
false
Here is a vbery string
true
8
22

Process finished with exit code 0

Tips:Wiki 几乎完全基于正则表达式。Wiki 内容基于来自用户的字符串输入,该输入被使用正则表达式解析和格式化。任何用户都可以通过输入一个 wiki 词组在 wiki 中创建另一个主题的链接,这个词组通常是一系列串联的单词,每个单词以一个大写字母开头
匹配目标: HereAllowed is a WikiWord followed by AnotherWikiWord,then SomeWikiWord.

  String input = "HereAllowed is a WikiWord followed by AnotherWikiWord,then SomeWikiWord.";
        Pattern pattern1 = Pattern.compile("[A-Z][a-z]*([A-Z][a-z]*)*");
        Matcher matcher = pattern1.matcher(input);
        while(matcher.find()){
            System.out.println(matcher.group());
        }

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=62138:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
HereAllowed
WikiWord
AnotherWikiWord
SomeWikiWord

那么回归上一节,正则表达式复杂模式下匹配大写字母开头的字符串类型,并用小括号进行分隔匹配,但我们只能用这种方法么? 在对字符串操作分组更多时,matcher.group(0),matcher.group(1)的效率显然不理想,所以我们引入"分组"的概念,将匹配得到的字符串作为模板,通过在替换字符串中包含 $0 来引用完整匹配结果,即matcher.group(0).当我们需要制定分组时,只需要指定模板变量$之后的数字下标即可

 //6th way
        String input = "Here is a WikiWord followed by AnotherWikiWord,then SomeWikiWord";
        Pattern pattern = Pattern.compile("[A-Z][a-z]*([A-z][a-z]*)*");
        Matcher mathcer = pattern.matcher(input);
        System.out.println("Before: "+input);
        String result = mathcer.replaceAll("blah$0blah");
        System.out.println("After:"+result);
        String result_update = mathcer.replaceAll("blah$1blah");
        System.out.println("After_update: "+result_update);

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=52384:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
Before: Here is a WikiWord followed by AnotherWikiWord,then SomeWikiWord
After:blahHereblah is a blahWikiWordblah followed by blahAnotherWikiWordblah,then blahSomeWikiWordblah
After_update: blahblah is a blahWordblah followed by blahWordblah,then blahWordblah

Process finished with exit code 0
 //6th way
        String input = "Here is a WikiWord followed by AnotherWikiWord,then SomeWikiWord";
        Pattern pattern = Pattern.compile("[A-Z][a-z]*([A-z][a-z]*)*");
        Matcher mathcer = pattern.matcher(input);
        System.out.println("Before: "+input);
        String result = mathcer.replaceAll("blah$0blah");
        System.out.println("After:"+result);
        String result_update = mathcer.replaceAll("blah$1blah");
        System.out.println("After_update: "+result_update);

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=52384:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
Before: Here is a WikiWord followed by AnotherWikiWord,then SomeWikiWord
After:blahHereblah is a blahWikiWordblah followed by blahAnotherWikiWordblah,then blahSomeWikiWordblah
After_update: blahblah is a blahWordblah followed by blahWordblah,then blahWordblah

构造思路:字符组建立
1.用\b用来分割字符串左侧为构成单词的字符,排除数字型前缀字符串。右侧为非单词字符,排除空格
2.使用[a-zA-Z_]字符组限制右侧出现的字符类型
3.使用\w*字符组匹配自此之前的字符串

 //7th way
        String line = "imooc";
        String Regex_second ="\\b[a-zA-Z_]\\w*";
        Pattern pattern2 = Pattern.compile(Regex_second);
        Matcher matcher2 = pattern2.matcher(line);
        if(matcher2.find()){
            System.out.println(matcher2.group());
        }
    }

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=49789:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
imooc

构造思路:
1、以引号开始,任意字符,以引号结束。
2、末尾引号左边不能是 \
3、末尾引号左边可以是 \\
4、末尾引号左边不能是 a\

 //8th way
        String line_second ="the\"laozi\"first";
        String Regex = "\"(.*?)(?<![^\\\\]\\\\)\"";
        Pattern pattern3 = Pattern.compile(Regex);
        Matcher matcher = pattern3.matcher(line_second);
        if(matcher.find()){
            System.out.println(matcher.group());
        }

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=64178:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
"laozi"

构造思路1:将$.转义分别用+截断分别匹配数字型字符

构造思路2:专用d+代替[0-9]匹配组

//9th way
        String dollar="$1000 fdgdfgdfgfdg";
        String Regex = "\\$[0-9]+(\\.[0-9][0-9])?";
        String Regex_first = "\\$\\d+(?:\\.\\d+)?";
        Pattern pattern = Pattern.compile(Regex_first);
        Matcher matcher = pattern.matcher(dollar);
        if(matcher.find()){
            System.out.println(matcher.group());
        }

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=55131:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
$1000

div标签(不含属性)正则式 : (?<=<div>).*(?=</div>)
div标签(含属性)正则式 : <div[^>]*>[^<>]*

Tips : 零宽断言
用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像 \b ^ $ \< \>这样的锚定作用,仅仅用于指定一个位置,不参与内容匹配,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。 断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配

(?<=<div>).*(?=</div>)正则解析

Tips : 贪婪模式
只要符合要求就一直匹配下去,直到无法匹配为止,即上面的结果就是2和3都存在,就往大的取!只取上限,包括、+、?都是一样的,例如ab.zz匹配abcxxzzsfewzzq的结果是abcxxzzsfewzz,并没有在abcxxzz处停止,而是直到最后的zzq不能再匹配时才停止匹配!

TestGreedyRegex.java

//13th way
        String test="a<tr>aava</tr>abb ";
        String reg="<.+>";
        System.out.println(test.replaceAll(reg,"###"));

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=61058:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
a###abb 

<div[^>]*>[^<>]*</div[^>]*>正则解析

过滤div标签

 String _input="<div>hhhhhhh</div>";
        String Regex ="<div[^>]*>[^<>]* ";
        String Regex_test="(?<=<div>).*(?=</div>)";
        Pattern pattern = Pattern.compile(Regex);
        Matcher matcher = pattern.matcher(etreeHtml);
        if(matcher.find()){
            System.out.println(matcher.group());
        }

img标签src正则式 : src\\s*=\\s*\"?(.*?)(\"|>|\\s+)
img标签(包括括号) : <img.*src\\s*=\\s*(.*?)[^>]*?>
过滤img标签

 String _input ="<img src=image/ad1.gif width=\"128\" height=\"36\"/>![](image/ad2.gif)";
        String Regex ="src\\s*=\\s*\"?(.*?)(\"|>|\\s+)";
        Pattern pattern = Pattern.compile(Regex);
        Matcher matcher = pattern.matcher(_input);
        boolean notice = matcher.find();
        System.out.println(notice);
        if(matcher.find()){
            System.out.println(matcher.group());
        }

style标签正则式:<[\s]*?style[^>]*?>[\s\S]*?<[\s]*?\/[\s]*?style[\s]*?>

Tips : 勉强模式:
如果说贪婪模式是最大匹配,那么勉强模式就是一种最小匹配。 Java是支持勉强模式的,勉强模式的表示方式是重复次数字符后面紧跟一个?,例如??就表示勉强模式的?+?就表示勉强模式的+*?就表示勉强模式的*{ }?就表示勉强模式的{ };其意义为一找到符合要求的就立马匹配成功,不再管后面的序列,在勉强模式下*匹配0个,+匹配一个,?匹配0个,而{ }只匹配下限

TestReluctantlyRegex

//13th way
        String test="a<tr>aava</tr>abb ";
        String reg="<.+?>";
        System.out.println(test.replaceAll(reg,"###"));

console output

D:\java\jdk1.8.0_51\bin\java "-javaagent:D:\idea\IntelliJ IDEA 2017.1.4\lib\idea_rt.jar=65466:D:\idea\IntelliJ IDEA 2017.1.4\bin" -Dfile.encoding=UTF-8 -classpath D:\java\jdk1.8.0_51\jre\lib\charsets.jar;D:\java\jdk1.8.0_51\jre\lib\deploy.jar;D:\java\jdk1.8.0_51\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_51\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_51\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_51\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_51\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_51\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_51\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_51\jre\lib\javaws.jar;D:\java\jdk1.8.0_51\jre\lib\jce.jar;D:\java\jdk1.8.0_51\jre\lib\jfr.jar;D:\java\jdk1.8.0_51\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_51\jre\lib\jsse.jar;D:\java\jdk1.8.0_51\jre\lib\management-agent.jar;D:\java\jdk1.8.0_51\jre\lib\plugin.jar;D:\java\jdk1.8.0_51\jre\lib\resources.jar;D:\java\jdk1.8.0_51\jre\lib\rt.jar;E:\kotlin_learn\out\production\kotlin_learn;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-runtime.jar;C:\Users\26645\.IntelliJIdea2017.1\config\plugins\Kotlin\kotlinc\lib\kotlin-reflect.jar;E:\kotlin_learn\junit-4.12.jar RegexTest
a###aava###abb 

<[\s]*?style[^>]*?>[\s\S]*?<[\s]*?\/[\s]*?style[\s]*?>正则解析 :

过滤style标签:

//        //10th
        StringBuilder etreeHtml =new StringBuilder("<html>\n" +
                "<head>\n" +
                "    <meta charset=\"utf-8\" />\n" +
                "    <title>HTML Editor</title>\n" +
                "    <style type=\"text/css\">\n" +
                "        .main { float: left;\n" +
                "        width: 100%; }\n" +
                " \n" +
                "        #editor { float: left;\n" +
                "        width: 49%;\n" +
                "        height: 600px;\n" +
                "        resize: none; }\n" +
                " \n" +
                "        #page { float: right;\n" +
                "        width: 49%;\n" +
                "        height: 600px;}\n" +
                "    </style>\n" +
                "</head>\n" +
                " \n" +
                "<body>\n" +
                "    <div class=\"main\">\n" +
                "        <p style=\"float:left; width:49%; color:red;\">This is your code.</p>\n" +
                "        <p style=\"float:right; width:49%; color:red;\">This is your page.</p>\n" +
                "    </div>\n" +
                " \n" +
                "    <div class=\"main\">\n" +
                "        <textarea id=\"editor\" onkeyup=\"showPage()\"></textarea>\n" +
                "        <div id=\"page\"></div>\n" +
                "    </div>\n" +
                "    <div>\n"+
                "      gfgfgfgfg\n"+
                "     </div>"+
                " \n" +
                "    <script type=\"text/javascript\">\n" +
                "        function showPage(){\n" +
                "            code = document.getElementById('editor').value;\n" +
                "            page = document.getElementById('page');\n" +
                "            page.innerHTML = code;\n" +
                "        }\n" +
                "    </script>\n" +
                " \n" +
                "</body>\n" +
                "</html>");
        String Regex = "(?id)<style\\s+(.*?)/?>";//匹配独立的img tags
        String Width_Regex = "(?ix)\\bwidth:(\\S+)";
        //定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
        String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
//        Matcher mStyle = Pattern.compile(Regex).matcher(etreeHtml);
//        Matcher mWidth =Pattern.compile(Width_Regex).matcher(etreeHtml);
        Pattern pattern = Pattern.compile(regEx_style);
        Matcher mStyle = pattern.matcher(etreeHtml);
        if(mStyle.find()){
            System.out.println(mStyle.group());
        }
上一篇下一篇

猜你喜欢

热点阅读