Javaの正規表現

巴扎黑
巴扎黑オリジナル
2017-06-26 11:28:111423ブラウズ

Java 正規表現

java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类:PatternMatcher。パターンは、正規表現のコンパイルされた表現パターンです。 Matcher オブジェクトは、一致パターンとしての Pattern オブジェクトに基づいて文字列をチェックするステート マシンです。 まず、Pattern インスタンスが、PERL に似た構文を使用して正規表現のコンパイルされたパターンをカスタマイズし、次に Matcher インスタンスが、指定された Pattern インスタンスのパターン コントロールの下で文字列一致を実行します。

正規表現の構築の概要

詳細な概要については、JDK の中国語ドキュメントを参照してください。以下に、一般的に使用されるいくつかの

n 回ではなく X、少なくとも n 回X、少なくとも n 回、ただし m 回を超えない
constructs match
. an をリストします。 y文字(行末文字と一致する場合もあれば一致しない場合もあります)
d 数字: [0-9]
D 非数字: [^0-9]
s 空白文字: [tnx0Bfr]
S 空白以外の文字: [^s]
w 単語文字: [a-zA-Z_0-9]
W 単語以外の文字: [^w]
[abc] a、b または c (単純)
[^abc] a、b または c (否定) を除く任意の文字
[a -zA -Z] a ~ z または A ~ Z、包括的 (範囲)
^ 行頭
$ 行末
X、一度ではない、または
X{n,}
X{n,m}

Pattern

正则表达式的编译表示形式,学过python的都知道这个和python的正则表达式有异曲同工之妙。 但是它的构造方法是私有的,因此不能直接创建对象,但是可以调用它的静态方法返回一个对象,下面会详细介绍

创建对象

  • Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,代码如下:

    //采用的complie(String regex)Pattern pattern = Pattern.compile("\\d+");    //采用的是complie(String regex,int flag)其中flag表示标志,下面的标志表示忽略字母大小写,详细的字段请看文档Pattern pattern=Pattern.compile("(CHEN)(\\D*)(\\d*)",Pattern.CASE_INSENSITIVE);

常用方法

  • Pattern compile(String regex) 用于创建Pattern对象

  • Pattern compile(String regex,int flags) 用于创建Pattern对象,并且指定了标志(比如忽略字母大小写)

  • int flags() 返回此模式的匹配标志

  • String pattern() 返回在其中编译过此模式的正则表达式。

  • String[] split(CharSequence input) 根据此模式的正则表达式将输入的字符串拆分成String数组,默认的都是全部拆分开

    //给出正则表达式用于匹配数字(0-9)Pattern pattern = Pattern.compile("\\d+");
    String str = "我是陈加兵456郑元梅34擦市场的逻辑啊";
    String[] splits = pattern.split(str, 2);   //结果:[我是陈加兵,郑元梅34擦市场的逻辑啊]
  • String[] split(CharSequence input,int limit) 将字符串按照正则表达式表示的内容进行分组,如果limit>0那么就分成limit个组,如果limit<0就按照默认全部分开

    //给出正则表达式用于匹配数字(0-9)Pattern pattern = Pattern.compile("\\d+");
    String str = "我是陈加兵456郑元梅34擦市场的逻辑啊";
    String[] splits = pattern.split(str, 2);   //结果:[我是陈加兵,郑元梅34擦市场的逻辑啊]
  • Pattern.matches(String regex,CharSequence input)是一个静态方法,用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串

    Pattern.matches("\\d+","2223");//返回true Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到 Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到
  • Matcher matcher(CharSequence input) 创建匹配给定输入与此模式的匹配器,现在只是先了解以下,下面会详细解释Matcher这个类

    Pattern p=Pattern.compile("\\d+"); 
    Matcher m=p.matcher("22bb23");

Matcher

Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持.
Matcher类和Pattern类一样它的构造方法同样是私有的,因此不能直接构造对象,但是上面我们说过Pattern类中有一个方法可以返回一个Matcher对象(matcher(CharSequence input))

常用的方法

  • boolean mathces() 尝试将整个区域与模式匹配(针对的是整个字符串,如果整个字符串未完全匹配,那么返回false,如果完全匹配那么返回true)

        Pattern pattern=Pattern.compile("\\d+");  //创建Pattern对象String str="I am hreo 1234";  //需要匹配的字符串Matcher matcher=pattern.matcher(str);//并没有完全匹配,因此返回false,如果str="123445",那么就会返回trueSystem.out.println(matcher.matches());
  • boolean lookingAt() 尝试从给定字符串的开头开始匹配,如果有子字符串匹配成功,那么返回true(针对的不是整个字符串,而是从开头开始,如果开头有一段字符串匹配成功,那么返回true)

        Pattern pattern=Pattern.compile("\\d+");  //创建Pattern对象String str="1234 I am a hero";  //需要匹配的字符串Matcher matcher=pattern.matcher(str);//开头的1234匹配到了,因此返回true,如果str="I am a hero  1234"将返回falseSystem.out.println(matcher.lookingAt());
  • int start() 匹配到的字符串的第一个元素的索引,如果没有匹配到调用此方法将会报错

  • int end() 匹配到的字符串的最后一个元素的索引,如果没有匹配到调用此方法将会报错

  • String group() 返回的是匹配到的字符串,如果没有匹配到调用此方法将会报错

        Pattern pattern=Pattern.compile("\\d+");  //创建Pattern对象String str="1234 I am a hero 33455";  //需要匹配的字符串Matcher matcher=pattern.matcher(str);if(matcher.lookingAt())
        {
            System.out.println("开始匹配到下标为"+matcher.start());  //0System.out.println("匹配结束的下标为"+matcher.end());    //4System.out.println("匹配的字符串为"+matcher.group());  //1234}
  • boolean find() 查找整个字符串,如果在任意位置有一段字符串能够匹配成功,那么返回true(任意位置),然后如果再次调用这个查找的话,那么就从上次查找到的末尾开始匹配,也就是说查找的是下一个子序列了

        Pattern pattern=Pattern.compile("\\d+");  //创建Pattern对象
        String str="1234 I am a hero 6666 chenjiabing8888";  //需要匹配的字符串
        Matcher matcher=pattern.matcher(str);
        while(matcher.find())  //如果还有匹配的字符序列
        {
            System.out.println("开始匹配到下标为"+matcher.start()); 
            System.out.println("匹配结束的下标为"+matcher.end());   
            System.out.println("匹配的字符串为"+matcher.group());  
        }  
        
    /*结果如下:
     * 
    开始匹配到下标为0
    匹配结束的下标为4
    匹配的字符串为1234
    开始匹配到下标为17
    匹配结束的下标为21
    匹配的字符串为6666
    开始匹配到下标为33
    匹配结束的下标为37
    匹配的字符串为8888
    */
    
    /*
     * 从上面返回的结果可以知道,find()可以匹配多次只要这个字符串还有可以匹配,
     * 并且每次的匹配字段的开始下标都是上一次匹配的结束字母的下一个下标
     */
  • boolean find(int start) 从指定的索引start位置开始匹配,这个用于重置find()匹配器,因为直接使用find()它的每次开始的索引都是不一样的

  • String group(int num) 返回指定分组匹配到的字符串,group(0)表示匹配到的整个字符串,group(1) 表示匹配到的第一个字符(即是第一个括号中匹配的模式)

  • int groupCount() 返回匹配到的分组个数

  • String replaceAll(String str) 将所有于模式相匹配的 字符串全部替换程指定的字符串str,返回的是替换后的文本

  • String replaceFirst(String str) 只将第一次匹配到的字符串替换成指定的字符串str,返回的时替换后的文本

        Pattern pattern=Pattern.compile("\\d+");
        String str="chenjiabing2344cal3445";
        Matcher matcher=pattern.matcher(str);
        str=matcher.replaceFirst("陈加兵");   
        System.out.println(str);   //输出:chenjiabing陈加兵cal3445/*         * str=matcher.replaceAll("陈加兵");         * System.out.println(str)    //输出:chenjiabing陈加兵cal陈加兵         */

捕获组

捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:

        ((A)(B(C)))
        (A)
        (B(C))
        (C)

总之在正则表达式中在括号中的就是一个分组,下面用一个实例来理解一下

        Pattern pattern=Pattern.compile("(\\D*)(\\d+)\\s(\\D+)");
        Matcher matcher=pattern.matcher("chenjiabingshizuibangde6666 chenjiabign");if(matcher.find())
        {
            System.out.println("总共匹配到了"+matcher.groupCount()+"个分组");
            System.out.println("匹配到整个字符串为"+matcher.group(0));
            System.out.println("匹配到的第一个字符串为"+matcher.group(1));
            System.out.println("匹配到的第二个字符串为"+matcher.group(2));
            System.out.println("匹配到的第三个字符串为"+matcher.group(3));
        }

贪婪模式和非贪婪模式

贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配
一般写python爬虫的时候使用的都是非贪婪模式来匹配
使用了贪婪模式后会尽可能匹配更多的字符串,即是到了正则表达式定的末尾但是还是会继续向后匹配,看看是否还能匹配,非贪婪模式则是相反,到了正则表达式定义的结束字符就直接停止匹配了
贪婪模式: .* , .+
非贪婪模式: .*? , .+?

实例

        //使用了贪婪模式,因此当匹配到第一个</div>的时候还要向后面匹配看看是否还能匹配到,由于后面还有</div>结尾的,因此还是能够匹配的,因此匹配到的是:陈加兵</div><div>郑元梅Pattern pattern=Pattern.compile("<div>(.*)</div>");   
        //使用了非贪婪模式,因此当匹配到第一个</div>的时候就不向后面匹配了,直接返回了,因此匹配到的是:陈加兵Pattern pattern1=Pattern.compile("<div>(.*?)</div>");   
        String str="<div>陈加兵</div><div>郑元梅</div>";
        Matcher matcher=pattern1.matcher(str);if(matcher.find())
        {
            System.out.println(matcher.groupCount());  //1System.out.println(matcher.group(1));  //输出匹配到的字符串,此时输出的是:陈加兵,如果使用贪婪模式输出的是:陈加兵</div><div>郑元梅}

以上がJavaの正規表現の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。