第二百零五节 Java正则表达式教程 - Java正则表达式边界、Java正则表达式组

Java正则表达式教程 - Java正则表达式边界

要匹配一行的开头,或匹配整个单词,不是任何单词的一部分,我们必须为匹配器设置边界。

下表列出了正则表达式中的边界匹配器

边界匹配含义
^一行的开始
$一行的结束
\b字边界
\B非字边界
\A输入的开始
\G上一次匹配的结束
\Z输入的结束,但是对于最终终止符,如果有的话
\z输入的结束

例子

以下代码演示了如何使用正则表达式匹配字边界。

public class Main {
  public static void main(String[] args) {
    // \\b to get \b inside the string literal.
    String regex = "\\bJava\\b";
    String replacementStr = "XML";
    String inputStr = "Java and Javascript";
    String newStr = inputStr.replaceAll(regex, replacementStr);

    System.out.println("Regular  Expression: " + regex);
    System.out.println("Input String: " + inputStr);
    System.out.println("Replacement String:  " + replacementStr);
    System.out.println("New String:  " + newStr);
  }
}

上面的代码生成以下结果。


 

Java正则表达式教程 - Java正则表达式组

我们可以通过括号将多个字符组合为一个单位。例如,(ab)

正则表达式中的每个组都有一个组号,从1开始。

Matcher类中的方法groupCount()返回与Matcher实例相关联的模式中的组数。

组0引用整个正则表达式和不由groupCount()方法报告。

正则表达式中的每个左括号标记新组的开始。

我们可以在正则表达式中返回引用组号。

假设我们要匹配以“abc"开头,后跟“xyz"的文本,后跟“abc"。

我们可以写一个正则表达式为“abcxyzabc"。

我们可以使用反向引用将正则表达式重写为“(abc)xyz \\ 1"。 \1 指第1组,即(abc)

\2 引用组2, \3 引用组3,依此类推。

以下代码显示如何显示格式化的电话号码。在正则表达式 \b(\d{3})(\d{3})(\d{4})\b \b 表示我们感兴趣的是仅在字边界匹配十个数字。

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

public class Main {
  public static void main(String[] args) {
    String regex = "\(\\d{3})(\\d{3})(\\d{4})\";

    Pattern p = Pattern.compile(regex);
    String source = "1234567890, 12345,  and  9876543210";

    Matcher m = p.matcher(source);

    while (m.find()) {
      System.out.println("Phone: " + m.group() + ", Formatted Phone:  ("
          + m.group(1) + ") " + m.group(2) + "-" + m.group(3));
    }
  }
}

上面的代码生成以下结果。

例子

以下代码显示如何引用替换文本中的组。

$n ,其中 n 是组编号,替换文本内部是指组 n 的匹配文本。

例如, $1 是指第一个匹配的组。要重新格式化电话号码,我们将使用($1) $2- $3 

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

public class Main {
  public static void main(String[] args) {
    String regex = "\(\\d{3})(\\d{3})(\\d{4})\";
    String replacementText = "($1) $2-$3";
    String source = "1234567890, 12345, and 9876543210";

    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(source);

    String formattedSource = m.replaceAll(replacementText);

    System.out.println("Text: " + source);
    System.out.println("Formatted Text: " + formattedSource);
  }
}

上面的代码生成以下结果。

命名组

我们可以在正则表达式中使用命名组。

我们可以命名一个组,然后使用他们的名字来引用参考组。

我们可以在替换文本中引用组名称,并使用组名称获取匹配的文本。

定义命名组的格式为

(?<groupName>pattern)

一对括号标记一个组。开始括号后面跟着一个?和放在尖括号中的组名称。

组名称只能包含字母和数字,且只能以字母开头。

以下正则表达式具有三个命名组。

  • areaCode
  • prefix
  • postPhoneNumber

正则表达式匹配10位数的电话号码。

(?<areaCode>\d{3})(?<prefix>\d{3})(?<postPhoneNumber>\d{4})

以下代码显示如何使用命名组。

String  replacementText = "(${areaCode}) ${prefix}-${postPhoneNumber}";

我们可以混合组号和组名。

上述正则表达式可以重写如下。

String  replacementText = "(${areaCode}) ${prefix}-$3";

以下代码显示如何在正则表达式中使用组名称以及如何在替换文本中使用名称。

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

public class Main {
  public static void main(String[] args) {
    String regex = "\(?<areaCode>\\d{3})(?<prefix>\\d{3})(?<postPhoneNumber>\\d{4})\";

    String replacementText = "(${areaCode}) ${prefix}-$3";
    String source = "1234567890 and 9876543210";
    Pattern p = Pattern.compile(regex);

    Matcher m = p.matcher(source);

    String formattedSource = m.replaceAll(replacementText);

    System.out.println("Text: " + source);
    System.out.println("Formatted Text: " + formattedSource);
  }
}

上面的代码生成以下结果。

组边界

我们可以使用 start() end()方法来获取组的匹配边界。 这些方法重载:

int start()
int start(int groupNumber)
int start(String groupName)
int end()
int end(int groupNumber)
int  end(String groupName)

方法返回上一次匹配的开始和结束。

以下代码显示如何匹配10位电话号码,并为每个成功匹配打印每个组的开始。

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

public class Main {
  public static void main(String[] args) {
    String regex = "\(?<areaCode>\\d{3})(?<prefix>\\d{3})(?<postPhoneNumber>\\d{4})\";
    String source = "1234567890, 12345, and 9876543210";
    Pattern p = Pattern.compile(regex);

    Matcher m = p.matcher(source);
    while (m.find()) {
      String matchedText = m.group();
      int start1 = m.start("areaCode");
      int start2 = m.start("prefix");
      int start3 = m.start("postPhoneNumber");
      System.out.println("Matched Text:" + matchedText);
      System.out.println("Area code start:" + start1);
      System.out.println("Prefix start:" + start2);
      System.out.println("Line Number start:" + start3);
    }
  }
}

上面的代码生成以下结果。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值