关于正则表达式的问题

java.lang包中的String类,java.util.regex包中的Pattern,Matcher类中都有matches()方法。
都与正则表达式有关。下面我分别举例:(字符串:"abc",正则表达式: "[a-z]{3}")
//更多正则表达式使用法则参考API
String类的方法:
boolean b = "abc".matches("[a-z]{3}" System.out.println(b);              
       字符串型替换: public static string replace (string text) {
                                    return text.replaceall("\\D","")
                                }//把非数字部分替换为空
        字符数组型查找并判断
        public static boolean char1(string text){
                        //查看你检测到的字符是否为数字,
                        char[] cs=text.tochararray();
                        for (int i=0;i<cs.length;i++){
                                char number =cs[i];//判断当前查看到的是否为数字
                                if(number<'0'||number>'9'){
                                            return false;}
                          }return true; }
Pattern类中的方法:
        boolean b = Pattern.matches("[a-z]{3}","abc");
        System.out.println(b);    
      public static void main(String[] args) {
                String str = "abdsfsf123sfsfs232df";
                       // 编译正则表达式生成一个Pattern对象
                Pattern pattern = Pattern.compile("\\d+");
                Matcher matcher = pattern.matcher(str);                   

Matcher类中的方法:
        Pattern p = Pattern.compile("[a-z]{3}");
        Matcher m = p.matcher("acc");
        boolean b =m.matches()
        System.out.println(b);              
得到的结果都为true。
2、String内建的正则表达式功能:
                String str = "-123";
                boolean isNum = str.matches("(-|\\+)?\\d+"); // 可能包含负号或者正号的整数
                 System.out.println(isNum);  // output: true
2.1、String类自带的正则表达式工具:
2.1.1、split方法:
这是String中提供的一个非常有用的正则表达式工具,作用是将字符串从正则表达式匹配的地方分开。
        // split方法演示
                    String content = "Hello, this is an iPad.";
                    String[] items = content.split("\\W+");  // 使用非单词字符分割字符串
                    System.out.println(Arrays.toString(items));  
                            //输出为  [Hello, this, is, an, iPad]  可以发现逗号也被当做分隔符给去掉了
        // split方法的重载版本,允许你限制字符串分割的次数
                    items = content.split("\\W+", 3);
                    System.out.println(Arrays.toString(items));
                             //输出为  [Hello, this, is an iPad.]
2.1.2、字符串替换之replaceFirst和replaceAll方法:
        // 字符串的替换  replaceFirst和replaceAll方法
                    String str = "You make me cry, make me smile.";
                    System.out.println(str.replaceFirst("m\\w+", "music"));  
                                //输出为 You music me cry, make me smile.
                    System.out.println(str.replaceAll("make|me", "music")); 
                                 // 输出为You music music cry, music music smile.
3、创建正则表达式:
3.1、Pattern和Matcher:
为了更加方便的使用正则表达式,强烈建议多去浏览JDK文档中java.util.regex.Pattern那一页的内容。
下面是一个用Java创建正则表达式的例子:
                String content = "one step tototoo far.";
                    // 编译正则表达式生成一个Pattern对象
                Pattern p = Pattern.compile("(to){2,}");
                // 用Pattern对象的matcher()方法检索字符串,生成Matcher对象
                Matcher m = p.matcher(content);
                while(m.find()){
                                System.out.println("Match \"" + m.group() + "\" ad position " + m.start() + "-" + (m.end() - 1));
                                // output: Match "tototo" ad position 9-14              }
                                
使用Matcher上的各种方法,可以判断各种不同类型的匹配是否成功:
                boolean matches():
    尝试将整个区域与模式匹配。
    如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。
    返回值(return): 当且仅当整个区域序列匹配此匹配器的模式时才返回 true。
 
                boolean lookingAt():
    尝试将从区域开头开始的输入序列与该模式匹配。
    与 matches 方法类似,此方法始终从区域的开头开始;与之不同的是,它不需要匹配整个区域。
    如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。
    返回: 当且仅当输入序列的前缀匹配此匹配器的模式时才返回 true。
 
                boolean find():
    尝试查找与该模式匹配的输入序列的下一个子序列。
    此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始。
    如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。
    返回: 当且仅当输入序列的子序列匹配此匹配器的模式时才返回 true。
 
                boolean find(int start):
    重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。
    如果匹配成功,则可通过 start、end 和 group 方法获取更多信息,而 find() 方法的后续调用将从此匹配操作未匹配的第一个字符开始。
    返回: 当且仅当从给定索引开始的输入序列的子序列匹配此匹配器的模式时才返回 true。
    抛出: IndexOutOfBoundsException- 如果开始点小于零或大于输入序列的长度。
 
            下面是一个使用 boolean find(int start)的例子:
                // boolean find(int start)
                    String content = "wings you are the hero~";
                    Pattern p = Pattern.compile("\\w+");
                    Matcher m = p.matcher(content);
                        int i=0;
                    while(m.find(i)){
                        System.out.print(m.group() + " ");
                                i++;      }
输出内容为:     wings ings ngs gs s you you ou u are are re e the the he e hero hero ero ro o
3.1.2、matches()与lookingAt()的使用
    下面是使用matches()和lookingAt()的例子:
        // 下面是Matcher的matches()和lookingAt()方法的使用举例
                String content = "It's my life, hero you are, no hero, wings you are the hero~";
                Pattern p = Pattern.compile("\\w*o");
                Matcher m = p.matcher(content);
                        while(m.find()){
                            System.out.println("find(): " + m.group() + " start at " + m.start() + " end at " + (m.end() - 1));
                            }
                        if(m.lookingAt()){
                            System.out.println("lookingAt(): " + m.group() + " start at " + m.start() + " end at " + (m.end() - 1));
                            }
                        if(m.matches()){
                            System.out.println("matches(): " + m.group() + " start at " + m.start() + " end at " + (m.end() - 1));
                            }
                输出结果为:
                        find(): hero start at 14 end at 17
                        find(): yo start at 19 end at 20
                        find(): no start at 28 end at 29
                        find(): hero start at 31 end at 34
                        find(): yo start at 43 end at 44
                        find(): hero start at 55 end at 58
可见matches()和lookingAt()方法并没有匹配到,这两个方法只有在正则表达式与输入的最开始处就开始匹配时才会成功,因为matches()只有在整个输入都匹配正则表达式时才会成功,而lookingAt()只要输入的第一部分匹配就会成功。
    如果要使matches()匹配到,则正则表达式可以这样写:
                Pattern p = Pattern.compile(".*life.*");
        输出结果为:
                matches(): It's my life, hero you are, no hero, wings you are the hero~ start at 0 end at 59
如果要使lookingAt()方法匹配到,则正则表达式可以这样写即可(加上.*也可以):
                Pattern p = Pattern.compile(".*life");
            输出结果为:     lookingAt(): It's my life start at 0 end at 11
3.2、Group:
    组是用括号划分的正则表达式,使用组的编号来引用某个组。
    组号为0表示整个表达式,组号为1表示被第一个括号括起来的组,以此类推。
举个例子:     (AB(C))D             0: ABCD 1:ABC 2:C
    Matcher中和Group相关的方法:
                    public int groupCount():
                    public String group():
                    public String group(i):
                    public int start(int group):
                    public int end(int group):
    下面是一个使用正则表达式组的例子:
                    String content = "It's my life,\n wings you are the hero~";
                    Pattern p = Pattern.compile("(?m)(\\S+)\\s+(\\S+\\s+\\S+)$");
    // 上面的(?m)是模式标记(后面有介绍),相当于Pattern.MULTILINE,表示多行模式也可以这样写:
    // Pattern p = Pattern.compile("(\\S+)\\s+(\\S+\\s+\\S+)$", Pattern.MULTILINE);
                    Matcher m = p.matcher(content);
                            if(m.find()){
                                for(int i=0; i<=m.groupCount(); i++){
                                             // 注意这里的groupCount不包含匹配到的整个字符串
                                            System.out.print("[" + m.group(i) + "]");
                                            // output: [It's my life,][It's][my life,]
                                        }
                                }
        注意:上面的(?m)是模式标记,表示多行模式,也可以使用Pattern.MULTILINE那种形式(后面会有介绍),
        输出为:          [It's my life,][It's][my life,]
        如果没有多行模式,则输出为:     [are the hero~][are][the hero~]
3.3、Pattern标记:
前面我们有一个例子包含了(?m)是模式标记,表示多行模式。这种多行模式在Pattern类的compile()方法的另外一个版本中可以声明:
                Pattern Pattern.compile(String regex, int flag);
                    其中flag来自以下的Pattern类中的常量:
CANON_EQ: 指定此标志后,当且仅当其完整规范分解匹配时,两个字符才可视为匹配。
                例如,当指定此标志时,表达式 "a\u030A" 将与字符串 "\u00E5" 匹配。默认情况下,匹配不考虑采用规范等价。
CASE_INSENSITIVE(?i): 默认情况下,不区分大小写的匹配假定仅匹配 US-ASCII 字符集中的字符。
                                可以通过指定 UNICODE_CASE 标志连同此标志来启用 Unicode 感知的、不区分大小写的匹配。
COMMENTS(?x): 此模式将忽略空白和在结束行之前以 # 开头的嵌入式注释。
DOTALL(?s): 在 dotall 模式中,表达式 . 可以匹配任何字符,包括行结束符。
                            默认情况下,此表达式不匹配行结束符。
MULTILINE(?m): 在多行模式中,表达式 ^ 和 $ 仅分别在行结束符前后匹配,或者在输入序列的结尾处匹配。
                            默认情况下,这些表达式仅在整个输入序列的开头和结尾处匹配。
UNICODE_CASE(?u): 指定此标志后,由 CASE_INSENSITIVE 标志启用时,不区分大小写的匹配将以符合 Unicode Standard 的方式完成。
                                    默认情况下,不区分大小写的匹配假定仅匹配 US-ASCII 字符集中的字符。
UNIX_LINES(?d): 在此模式中,.、^ 和 $ 的行为中仅识别 '\n' 行结束符。
在这些标记中Pattern.CASE_INSENSITIVE, Pattern.MULTILINE以及Pattern.COMMENTS(对声明或文档有用)特别有用。你还可以通过“或”(|)操作符组合多个标记的功能:
            Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
            Matcher m = p.matcher("java is a programming language\n JAVA");
                            while(m.find()){
                                        System.out.println(m.group());
                                }
            输出为:         java         JAVA
3.4、split()方法:
        与String的split()方法类似,只不过使用格式反过来了:
                String content = "Wings- you are -the -hero~";
                System.out.println(Arrays.toString(Pattern.compile("-").split(content))); 
                    System.out.println(Arrays.toString(Pattern.compile("-").split(content, 2)));
        输出为:
                        [Wings,  you are , the , hero~]
                        [Wings,  you are -the -hero~]
3.5、替换操作:
主要看到Matcher的以下几个方法:
        replaceAll
                    public String replaceAll(String replacement)
                    替换模式与给定替换字符串相匹配的输入序列的每个子序列。
        replaceFirst
                    public String replaceFirst(String replacement)
                    替换模式与给定替换字符串匹配的输入序列的第一个子序列。
        appendReplacement
                    public Matcher appendReplacement(StringBuffer sb,  String replacement)
    实现非终端添加和替换步骤。此方法执行以下操作:
            它从添加位置开始在输入序列读取字符,并将其添加到给定字符串缓冲区。
            在读取以前匹配之前的最后字符(即位于索引 start() - 1 处的字符)之后,它就会停止。
            它将给定替换字符串添加到字符串缓冲区。
            它将此匹配器的添加位置设置为最后匹配位置的索引加 1,即 end()。
 
        appendTail
                    public StringBuffer appendTail(StringBuffer sb)
        实现终端添加和替换步骤。此方法从添加位置开始从输入序列读取字符,并将其添加到给定字符串缓冲区。
            可以在一次或多次调用 appendReplacement 方法后调用它来复制剩余的输入序列。
下面通过一个程序来演示一下这几个方法的使用,并且通过这个程序,更加熟悉正则表达式的使用:
            String content = "/*! long   long  ago, the is a man called Jack, \n" +   " he has one boat. !*/";
                // Pattern.DOTALL: 这种模式下 . 可以匹配任何字符,包括换行符
            Pattern p = Pattern.compile("/\\*!(.*)!\\*/", Pattern.DOTALL);
            Matcher m = p.matcher(content);
                if(m.find())     // 匹配到/*! !*/中的内容
                content = m.group(1); // 把两个以上空格的地方缩减为一个空格
                content = content.replaceAll(" {2,}", " ");
                // 开启多行模式,删除每一行开头部分的空格,+表示匹配一个或多个
                content = content.replaceAll("(?m)^ +", "");
                // 匹配到字符串中的第一个元音字母,并替换为VOWEL
                content = content.replaceFirst("[aeiou]", "VOWEL");
                // 下面一段程序演示把字符串中的所有元音字母替换为大写
                Pattern p1 = Pattern.compile("[aeiou]");
                Matcher m1 = p1.matcher(content);
                StringBuffer sb = new StringBuffer();
                while(m1.find()){   // 非终端添加和替换,
                        m1.appendReplacement(sb, m1.group().toUpperCase());
                    }
                m1.appendTail(sb); // 终端添加和替换
                System.out.println(sb);
        输出结果为:
                lVOWELng lOng AgO, thE Is A mAn cAllEd JAck,
                hE hAs OnE bOAt.
注意,上面的两个替换操作都只使用了一次replaceAll(),
            所以,与其编译为Pattern,不如直接使用String的replaceAll()方法,而且开销也比较小。
3.6、reset()方法:
    如果要讲一个现有的Matcher对象运用于一个新的字符序列,可以使用reset()方法,
    如果使用不带参数的reset()方法,则可以将Matcher对象重新设置到当前字符序列的起始位置:
            Matcher m = Pattern.compile("[hks][io][sbo]")
               .matcher("This is the key.");
            while(m.find())
            System.out.println(m.group()); // output: his
            // 把Matcher应用于一个新的字符序列
            m.reset("New version");
            while(m.find())
            System.out.println(m.group()); // output: sio
4、正则表达式与Java I/O
下面通过一个字符串的ArrayList模拟文本的逐行读取。
        这里在循环外创建了一个空的Matcher对象,然后用reset()方法每次为Matcher加载一次输入,这样处理会有一定 性能优化:
        ArrayList<String> list = new ArrayList<String>();
            list.add("This is String...");
            list.add("Big blue ocean");
            list.add("Search something");
            Pattern p = Pattern.compile("\\b[Ssb]\\w+", Pattern.CASE_INSENSITIVE);
            Matcher m = p.matcher("");
            for(String line : list){
                m.reset(line);
                while(m.find()){
                System.out.println(m.group() + ": start at " + m.start());
                    }
            }
        输出结果为:
            String: start at 8
            Big: start at 0
            blue: start at 4
            Search: start at 0
            something: start at 7
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值