Java正規表現のサンプルコードの詳細説明

黄舟
リリース: 2017-03-30 10:57:44
オリジナル
1462 人が閲覧しました

Java は、java.util.regex パッケージの下で強力な 通常の API を提供します。このチュートリアルでは、次のことを示します。正規表現 API の使用方法。

正規表現

正規表現は、

検索に使用されるテキスト パターンです。つまり、テキスト内のパターンの出現を検索することができます。 Web ページのハイパーリンク

正規表現の例

テキスト内を検索するための簡単な Java 正規表現の例です。http://

String text    =
        "This is the text to be searched " +
        "for occurrences of the http:// pattern.";
String pattern = ".*http://.*";
boolean matches = Pattern.matches(pattern, text);
System.out.println("matches = " + matches);
ログイン後にコピー

サンプル コード実際には、http が見つかったかどうかは検出されません。 // は、ドメイン名とサフィックス (.com、.net など) を含む正当なハイパーリンクの一部です。コードは、正規表現に関する

API が表示されるかどうかをチェックするだけです。 Java6

このチュートリアルでは、Java6 の正規表現に関する API を紹介します

Pattern (java.util.regex.Pattern)

クラス java.util.regex.Pattern は、略して Pattern と呼ばれます。これは、Java 正規表現の入り口です。正規表現を使用する必要がある場合は、必ずパターン クラスから始めてください。正規表現パターンがテキストに一致するかどうかを確認する最も直接的な方法は、

static

メソッド パターンを呼び出すことです。 .matches() の例は次のとおりです:

String text    =
        "This is the text to be searched " +
        "for occurrences of the pattern.";
String pattern = ".*is.*";
boolean matches = Pattern.matches(pattern, text);
System.out.println("matches = " + matches);
ログイン後にコピー

上記のコードは、単語 "is" が

変数

テキストに出現するかどうかを検索し、"is" の前後に 0 文字以上の文字が含まれていることを許可します (.matches() で指定)。 *)

Pattern.matches() メソッドは、パターンがテキスト内に 1 回出現するかどうかを確認するのに適しています。または、Pattern クラスのデフォルト設定に適用されます。

複数の出現に一致する必要がある場合は、異なる一致するテキストを出力することもできます。デフォルト以外の設定では、Pattern.compile() メソッドを使用してパターン インスタンスを取得する必要があります。テキスト内に複数回出現する正規表現と一致する必要がある場合は、 Pattern.compile() メソッドを使用して作成する必要があります。Pattern

オブジェクト の例は次のとおりです。

String text    =
        "This is the text to be searched " +
        "for occurrences of the http:// pattern.";
String patternString = ".*http://.*";
Pattern pattern = Pattern.compile(patternString);
ログイン後にコピー

Compile メソッドで特別なフラグを指定できます:

Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
ログイン後にコピー

Pattern クラスには複数のフラグ (int 型) が含まれています。 ) を使用して、Pattern が上記のコード内のパターンと一致する方法を制御できます。パターン マッチングの大文字と小文字を区別しないようにします

Pattern.matcher()

Pattern オブジェクトを取得したら、Matcher オブジェクトを取得できます。 Matcher の例は、テキスト内のパターンを照合するために使用されます。例は次のとおりです

Matcher matcher = pattern.matcher(text);
ログイン後にコピー
Matcher クラスには、テキストがパターンと一致するかどうかを確認できるmatches() メソッドがあります。以下は、Matcher の完全な例です
String text    =
        "This is the text to be searched " +
        "for occurrences of the http:// pattern.";
String patternString = ".*http://.*";
Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
boolean matches = matcher.matches();
System.out.println("matches = " + matches);
ログイン後にコピー

Pattern.split()

Pattern クラスの split() メソッドは、区切り文字として正規表現を使用して、テキストを String 型の

配列

に分割できます。例:

String text = "A sep Text sep With sep Many sep Separators";
String patternString = "sep";
Pattern pattern = Pattern.compile(patternString);
String[] split = pattern.split(text);
System.out.println("split.length = " + split.length);
for(String element : split){
    System.out.println("element = " + element);
}
ログイン後にコピー

上記の例では、テキストは 5 つの文字列を含む配列に分割されます。

Pattern.pattern()

Pattern クラスのパターンは、Pattern オブジェクトの作成に使用される正規表現を返します。例:

String patternString = "sep";
Pattern pattern = Pattern.compile(patternString);
String pattern2 = pattern.pattern();
ログイン後にコピー

上記のコードの pattern2 の値は sep であり、patternString 変数と同じです。

Matcher (java.util.regex.Matcher)

java.util.regex.Matcher クラスは、テキスト内の複数の正規表現の一致に使用されます。Matcher は、複数のテキスト内の同じ正規表現の一致にも適しています。テキスト。

Matcher には便利なメソッドが多数あります。詳細については、公式 JavaDoc を参照してください。ここではコアとなるメソッドのみを紹介します。

次のコードは、Matcher の使用方法を示しています

String text    =
        "This is the text to be searched " +
        "for occurrences of the http:// pattern.";
String patternString = ".*http://.*";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
boolean matches = matcher.matches();
ログイン後にコピー

まずパターンを作成し、次に Matcher を取得し、matches() メソッドを呼び出し、パターンの一致を示す場合は true を返し、一致しないことを示す場合は false を返します。

Matcher を使用するとさらに多くのことができます。

Matcher の作成

Pattern の matcher() メソッドを使用して Matcher を作成します。

String text    =
        "This is the text to be searched " +
        "for occurrences of the http:// pattern.";

String patternString = ".*http://.*";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
ログイン後にコピー

matches()

Matcher クラスのmatches()メソッドは、テキスト内の正規表現と一致するために使用されます

boolean matches = matcher.matches();
ログイン後にコピー

テキストが正規表現と一致する場合、matches()メソッドはtrueを返します。それ以外の場合は false を返します。

matches() メソッドを使用して正規表現の複数の出現を検索することはできません。必要に応じて、find()、start()、

end

() メソッドを使用します。

LookingAt()

LookingAt() はmatches() メソッドに似ていますが、最大の違いは、lookingAt() メソッドはテキストの先頭の正規表現に一致するのに対し、

matches() は正規表現に一致することです。テキスト全体について。つまり、正規表現がテキスト全体ではなくテキストの先頭に一致する場合、lookingAt() は true を返し、matches() は false を返します。 例:

String text    =
        "This is the text to be searched " +
        "for occurrences of the http:// pattern.";
String patternString = "This is the";
Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
System.out.println("lookingAt = " + matcher.lookingAt());
System.out.println("matches   = " + matcher.matches());
ログイン後にコピー

上記の例は、テキストの先頭とテキスト全体の正規表現「this is the」にそれぞれ一致します。テキストの先頭に一致するメソッド (lookAt()) は true を返します。

对整个文本匹配正则表达式的方法 (matches()) 返回false,因为 整个文本包含多余的字符,而 正则表达式要求文本精确匹配”this is the”,前后又不能有额外字符。

find() + start() + end()

find() 方法用于在文本中查找出现的正则表达式,文本是创建Matcher时,通过 Pattern.matcher(text) 方法传入的。如果在文本中多次匹配,find() 方法返回第一个,之后每次调用 find() 都会返回下一个。

start() 和 end() 返回每次匹配的字串在整个文本中的开始和结束位置。实际上, end() 返回的是字符串末尾的后一位,这样,可以在把 start() 和 end() 的返回值直接用在String.substring() 里。

String text    =
        "This is the text which is to be searched " +
        "for occurrences of the word 'is'.";
String patternString = "is";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
int count = 0;
while(matcher.find()) {
    count++;
    System.out.println("found: " + count + " : "  + matcher.start() + " - " + matcher.end());
}
ログイン後にコピー

这个例子在文本中找到模式 “is” 4次,输出如下:

found: 1 : 2 - 4
 found: 2 : 5 - 7
 found: 3 : 23 - 25
 found: 4 : 70 - 72
ログイン後にコピー

reset()

reset() 方法会重置Matcher 内部的 匹配状态。当find() 方法开始匹配时,Matcher 内部会记录截至当前查找的距离。调用 reset() 会重新从文本开头查找。

也可以调用 reset(CharSequence) 方法. 这个方法重置Matcher,同时把一个新的字符串作为参数传入,用于代替创建 Matcher 的原始字符串。

group()

假设想在一个文本中查找URL链接,并且想把找到的链接提取出来。当然可以通过 start()和 end()方法完成。但是用group()方法更容易些。

分组在正则表达式中用括号表示,例如:

(John)

此正则表达式匹配John, 括号不属于要匹配的文本。括号定义了一个分组。当正则表达式匹配到文本后,可以访问分组内的部分。

使用group(int groupNo) 方法访问一个分组。一个正则表达式可以有多个分组。每个分组由一对括号标记。想要访问正则表达式中某分组匹配的文本,可以把分组编号传入 group(int groupNo)方法。

group(0) 表示整个正则表达式,要获得一个有括号标记的分组,分组编号应该从1开始计算。

String text    =  "John writes about this, and John writes about that," +
                        " and John writes about everything. "  ;
String patternString1 = "(John)";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);
while(matcher.find()) {
    System.out.println("found: " + matcher.group(1));
}
ログイン後にコピー

以上代码在文本中搜索单词John.从每个匹配文本中,提取分组1,就是由括号标记的部分。输出如下

found: John
 found: John 
found: John
ログイン後にコピー

多分组

上面提到,一个正则表达式可以有多个分组,例如:

(John) (.+?)

这个表达式匹配文本”John” 后跟一个空格,然后跟1个或多个字符,最后跟一个空格。你可能看不到最后的空格。

这个表达式包括一些字符有特别意义。字符 点 . 表示任意字符。 字符 + 表示出现一个或多个,和. 在一起表示 任何字符,出现一次或多次。字符? 表示 匹配尽可能短的文本。

完整代码如下

String text    =
          "John writes about this, and John Doe writes about that," +
                  " and John Wayne writes about everything."
        ;
String patternString1 = "(John) (.+?) ";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);
while(matcher.find()) {
    System.out.println("found: " + matcher.group(1) +
                       " "       + matcher.group(2));
}
ログイン後にコピー

注意代码中引用分组的方式。代码输出如下

found: John writes 
found: John Doe 
found: John Wayne
ログイン後にコピー

嵌套分组

在正则表达式中分组可以嵌套分组,例如

((John) (.+?))
ログイン後にコピー

这是之前的例子,现在放在一个大分组里.(表达式末尾有一个空格)。

当遇到嵌套分组时, 分组编号是由左括号的顺序确定的。上例中,分组1 是那个大分组。分组2 是包括John的分组,分组3 是包括 .+? 的分组。当需要通过groups(int groupNo) 引用分组时,了解这些非常重要。

以下代码演示如何使用嵌套分组

String text    =
          "John writes about this, and John Doe writes about that," +
                  " and John Wayne writes about everything."
        ;
String patternString1 = "((John) (.+?)) ";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);
while(matcher.find()) {
    System.out.println("found:   ");
}
ログイン後にコピー

输出如下

found: 
 found: 
 found:
ログイン後にコピー

replaceAll() + replaceFirst()

replaceAll() 和 replaceFirst() 方法可以用于替换Matcher搜索字符串中的一部分。replaceAll() 方法替换全部匹配的正则表达式,replaceFirst() 只替换第一个匹配的。

在处理之前,Matcher 会先重置。所以这里的匹配表达式从文本开头开始计算。

示例如下

String text    =
          "John writes about this, and John Doe writes about that," +
                  " and John Wayne writes about everything."
        ;
String patternString1 = "((John) (.+?)) ";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);

String replaceAll = matcher.replaceAll("Joe Blocks ");
System.out.println("replaceAll   = " + replaceAll);

String replaceFirst = matcher.replaceFirst("Joe Blocks ");
System.out.println("replaceFirst = " + replaceFirst);
ログイン後にコピー

输出如下

replaceAll = Joe Blocks about this, and Joe Blocks writes about that,

and Joe Blocks writes about everything.

replaceFirst = Joe Blocks about this, and John Doe writes about that,

and John Wayne writes about everything.
ログイン後にコピー

输出中的换行和缩进是为了可读而增加的。

注意第1个字符串中所有出现 John 后跟一个单词 的地方,都被替换为 Joe Blocks 。第2个字符串中,只有第一个出现的被替换。

appendReplacement() + appendTail()

appendReplacement() 和 appendTail() 方法用于替换输入文本中的字符串短语,同时把替换后的字符串附加到一个 StringBuffer 中。

当find() 方法找到一个匹配项时,可以调用 appendReplacement() 方法,这会导致输入字符串被增加到StringBuffer 中,而且匹配文本被替换。 从上一个匹配文本结尾处开始,直到本次匹配文本会被拷贝。

appendReplacement() 会记录拷贝StringBuffer 中的内容,可以持续调用find(),直到没有匹配项。

直到最后一个匹配项目,输入文本中剩余一部分没有拷贝到 StringBuffer. 这部分文本是从最后一个匹配项结尾,到文本末尾部分。通过调用 appendTail() 方法,可以把这部分内容拷贝到 StringBuffer 中.

String text    =
          "John writes about this, and John Doe writes about that," +
                  " and John Wayne writes about everything."
        ;

String patternString1 = "((John) (.+?)) ";
Pattern      pattern      = Pattern.compile(patternString1);
Matcher      matcher      = pattern.matcher(text);
StringBuffer stringBuffer = new StringBuffer();

while(matcher.find()){
    matcher.appendReplacement(stringBuffer, "Joe Blocks ");
    System.out.println(stringBuffer.toString());
}
matcher.appendTail(stringBuffer);
System.out.println(stringBuffer.toString());
ログイン後にコピー

注意我们在while循环中调用appendReplacement() 方法。在循环完毕后调用appendTail()。 代码输出如下:

Joe Blocks
 Joe Blocks about this, and Joe Blocks
 Joe Blocks about this, and Joe Blocks writes about that, and Joe Blocks
 Joe Blocks about this, and Joe Blocks writes about that, and Joe Blocks
 writes about everything.
ログイン後にコピー

Java 正则表达式语法

为了更有效的使用正则表达式,需要了解正则表达式语法。正则表达式语法很复杂,可以写出非常高级的表达式。只有通过大量的练习才能掌握这些语法规则。

本篇文字,我们将通过例子了解正则表达式语法的基础部分。介绍重点将会放在为了使用正则表达式所需要了解的核心概念,不会涉及过多的细节。详细解释,参见 Java DOC 中的 Pattern 类.

基本语法

在介绍高级功能前,我们先快速浏览下正则表达式的基本语法

字符

是正则表达式中最经常使用的的一个表达式,作用是简单的匹配一个确定的字符。例如:

John
ログイン後にコピー

这个简单的表达式将会在一个输入文本中匹配John文本。

可以在表达式中使用任意英文字符。也可以使用字符对于的8进制,16进制或unicode编码表示。例如:

101

\x41

\u0041
ログイン後にコピー

以上3个表达式 都表示大写字符A。第一个是8进制编码(101),第2个是16进制编码(41),第3个是unicode编码(0041).

字符分类

字符分类是一种结构,可以针对多个字符匹配而不只是一个字符。换句话说,一个字符分类匹配输入文本中的一个字符,对应字符分类中多个允许字符。例如,你想匹配字符 a,b 或c,表达式如下:

[abc]
ログイン後にコピー

用一对方括号[] 表示字符分类。方括号本身并不是要匹配的一部分。

可以用字符分类完成很多事。例如想要匹配单词John,首字母可以为大写和小写J.

[Jj]ohn
ログイン後にコピー

字符分类[Jj] 匹配J或j,剩余的 ohn 会准确匹配字符ohn.

预定义字符分类

正则表达式中有一些预定义的字符分类可以使用。例如, \d 表示任意数字, \s 表示任意空白字符,\w 表示任意单词字符。

预定义字符分类不需要括在方括号里,当然也可以组合使用

\d

[\d\s]
ログイン後にコピー

第1个匹配任意数字,第2个匹配任意数字或空白符。

完整的预定义字符分类列表,在本文最后列出。

边界匹配

正则表达式支持匹配边界,例如单词边界,文本的开头或末尾。例如,\w 匹配一个单词,^匹配行首,$ 匹配行尾。

^This is a single line$
ログイン後にコピー

上面的表达式匹配一行文本,只有文本 This is a single line。注意其中的行首和行尾标志,表示不能有任何文本在文本的前面后后面,只能是行首和行尾。

完整的匹配边界列表,在本文最后列出。

量词匹配

量词可以匹配一个表达式多次出现。例如下列表达式匹配字母A 出现0次或多次。

A*
ログイン後にコピー

量词 * 表示0次或多次。+ 表示1次或多次。? 表示0次或1次。还有些其他量词,参见本文后面的列表。

量词匹配分为 饥饿模式,贪婪模式,独占模式。饥饿模式 匹配尽可能少的文本。贪婪模式匹配尽可能多的文本。独占模式匹配尽可能多的文本,甚至导致剩余表达式匹配失败。

以下演示饥饿模式,贪婪模式,独占模式区别。假设以下文本:

John went for a walk, and John fell down, and John hurt his knee.
ログイン後にコピー

饥饿模式下 表达式:

John.*?
ログイン後にコピー

这个表达式匹配John 后跟0个或多个字符。 . 表示任意字符。* 表示0或多次。? 跟在 * 后面,表示 * 采用饥饿模式。

饥饿模式下,量词只会匹配尽可能少的字符,即0个字符。上例中的表达式将会匹配单词John,在输入文本中出现3次。

如果改为贪婪模式,表达式如下:

John.*
ログイン後にコピー

贪婪模式下,量词会匹配尽可能多的字符。现在表达式会匹配第一个出现的John,以及在贪婪模式下 匹配剩余的所有字符。这样,只有一个匹配项。

最后,我们改为独占模式:

John.*+hurt
ログイン後にコピー

*后跟+ 表示独占模式量词。

这个表达式在输入文本中没有匹配项,尽管文本中包括 John 和 hurt. 为什么会这样? 因为 .*+ 是独占模式。与贪婪模式下,尽可能多的匹配文本,以使整个表达式匹配不同。独占模式会尽可能的多的匹配,但不考虑表达式剩余部分是否能匹配上。

.*+ 将会匹配第一个John之后的所有字符,这会导致表达式中剩余的 hurt 没有匹配项。如果改为贪婪模式,会有一个匹配项。表达式如下:

John.*hurt
ログイン後にコピー

逻辑操作符

正则表达式支持少量的逻辑运算(与,或,非)。

与操作是默认的,表达式 John ,意味着J 与 o与h与n。

或操作需要显示指定,用 | 表示。例如表达式 John|hurt 意味着John 或 hurt 。

字符

. 任意英文字母
\\ 反斜杠, 单独的反斜杠做为转义字符,与其他特殊字符一起使用。如果想匹配反斜杠本身,需要转义。两个反斜杠实际匹配一个反斜杠n字符的8进制表示.n 在0至7之间取值
nn 字符的8进制表示.n 在0至7之间取值
mnn 字符的8进制表示. m 在0至3之间取值, n 在0至7之间取值
\xhh 字符的16进制表示.
\uhhhh 字符的16进制表示 0xhhhh. 对应unicode 编码字符
\t 缩进符.
\n 换行符 (unicode: ‘\u000A’)
\r 回车符 (unicode: ‘\u000D’)
\f 制表符 (unicode: ‘\u000C’)
\a 警报(铃声)字符 (unicode: ‘\u0007′)
\e 转义符 (unicode: ‘\u001B’)
\cx 控制符 x

字符分类

[abc] 匹配 a, 或 b 或 c
[^abc] 匹配不是a,b,c 的字符,是否定匹配
[a-zA-Z] 匹配a 到 z ,A到Z 直接的字符,是范围匹配
[a-d[m-p]] 匹配a到d之间字符或 m到p之间字符,是并集匹配
[a-z&&[def]] 匹配 d, e, 或 f. 是交集匹配 (这里是在范围 a-z和字符def之间取交集).
[a-z&&[^bc]] 匹配a-z 之间所有字符,排除bc的字符。是减法匹配
[a-z&&[^m-p]] 匹配a-z 之间所有字符,排除m-p之间的字符是减法匹配

内置字符分类

. 匹配任意一个字符,根据创建Pattern是传入的标志,可能匹配行结尾符
\d 匹配任意数字 [0-9]
\D 匹配任意非数字 [^0-9]
\s 匹配任意空白符 (空格, 缩进, 换行,回车)
\S 匹配任意非空白符
\w 匹配任意单词
\W 匹配任意非单词

边界匹配

^ 匹配行首
$ 匹配行尾
\b 匹配单词边界
\B 匹配非单词边界
\A 匹配文本开头
\G 匹配前一匹配项结尾
\Z Matches the end of the input text except the final terminator if any
\z 匹配文本结尾

量词

贪婪模式 饥饿模式 独占模式
X? X?? X?+ 匹配0或1次
X* X*? X*+ 匹配0或多次
X+ X+? X++ 匹配1或多次
X{n} X{n}? X{n}+ 匹配n次
X{n,} X{n,}? X{n,}+ 匹配最少n次
X{n, m} X{n, m}? X{n, m}+ 匹配最少n次,最多m次

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

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート