JavaRush /Java Blog /Random-TW /Java 中的正規表示式,第 4 部分

Java 中的正規表示式,第 4 部分

在 Random-TW 群組發布
我們向您展示 Java 正規表示式簡短指南的翻譯,該指南由 Jeff Friesen 為javaworld網站編寫。為了方便閱讀,我們將文章分成幾個部分。 Java 中的正規表示式,第 4 部分 - 1 Java 中的正規表示式,第 1 部分 Java 中的正規表示式,第 2 部分 Java 中的正規表示式,第 3 部分

處理捕獲組的方法

應用程式原始碼RegexDemo包括方法呼叫m.group()。該方法是該類別旨在處理捕獲組 group()的幾種方法之一:Matcher
  • 此方法int groupCount()傳回解析器模式中捕獲的組的數量。該數字不考慮特殊捕獲組編號 0,它對應於整個模式。

  • 該方法String group()傳回找到的上一個符合的字元。要報告空字串的成功搜索,此方法傳回空字串。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

  • 該方法String group(int group)與前面的方法類似,不同之處在於它返回上一個匹配的字符,由參數指定的組號捕獲group。請注意,這group(0)相當於group(). 如果模板沒有具有給定編號的捕獲組,則該方法將引發異常IndexOutOfBoundsException。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

  • 此方法String group(String name)傳回由名稱群組擷取的上一個符合項的字元。如果捕獲的組名不在模板中,則會拋出異常IllegalArgumentException。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

以下範例示範了groupCount()和方法的使用group(int group)
Pattern p = Pattern.compile("(.(.(.)))");
Matcher m = p.matcher("abc");
m.find();
System.out.println(m.groupCount());
for (int i = 0; i <= m.groupCount(); i++)
System.out.println(i + ": " + m.group(i));
執行結果:
3
0: abc
1: abc
2: bc
3: c
Java 中的正規表示式,第 4 部分 - 2

確定比賽位置的方法

該類別Matcher提供了幾種返回匹配開始和結束位置的方法:
  • 此方法int start()傳回找到的上一個符合項的起始位置。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

  • 此方法int start(int group)與前面的方法類似,但傳回為參數 指定編號的群組找到的上一個符合項的起始位置group。如果模板沒有具有給定編號的捕獲組,則該方法將引發異常IndexOutOfBoundsException。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

  • 此方法int start(String name)與前面的方法類似,但傳回為名為 的群組找到的上一個符合項的起始位置name。如果捕獲的群組name不在模板中,則會拋出異常IllegalArgumentException。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

  • 此方法int end()傳回上一次找到的匹配的最後一個字元的位置加1。如果匹配器尚未執行匹配或上一次搜尋操作失敗,則會拋出異常IllegalStateException

  • 此方法int end(int group)與前面的方法類似,但傳回為參數 指定編號的群組找到的上一個符合項的結束位置group。如果模板沒有具有給定編號的捕獲組,則該方法將引發異常IndexOutOfBoundsException。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

  • 此方法int end(String name)與前面的方法類似,但傳回為名為 的群組找到的上一個符合項的結束位置name。如果捕獲的群組name不在模板中,則會拋出異常IllegalArgumentException。如果解析器尚未執行查找或先前的查找操作失敗,則會拋出異常IllegalStateException

以下範例示範了兩種輸出擷取組編號 2 的開始/結束匹配位置的匹配位置方法:
Pattern p = Pattern.compile("(.(.(.)))");
Matcher m = p.matcher("abcabcabc");
while (m.find())
{
   System.out.println("Найдено " + m.group(2));
   System.out.println("  начинается с позиции " + m.start(2) +
                      " и заканчивается на позиции " + (m.end(2) - 1));
   System.out.println();
}
此範例的輸出如下:
Найдено bc
начинается с позиции 1 и заканчивается на позиции 2
Найдено bc
начинается с позиции 4 и заканчивается на позиции 5
Найдено bc
начинается с позиции 7 и заканчивается на позиции 8

PatternSyntaxException 類別的方法

該類別的實例PatternSyntaxException描述了正規表示式中的語法錯誤。從方法compile()matches()類別中拋出此類異常Pattern,並透過以下建構函式形成: PatternSyntaxException(String desc, String regex, int index) 此建構函式儲存指定的描述 ( desc)、正規表示式( regex) 以及發生語法錯誤的位置。如果語法錯誤的位置未知,則該值index設為-1。最有可能的是,您永遠不需要創建PatternSyntaxException. 但是,在建立格式化錯誤訊息時,您將需要提取上述值。為此,您可以使用以下方法:
  • 該方法String getDescription()傳回語法錯誤的描述。
  • 此方法int getIndex()傳回錯誤發生的位置,如果位置未知,則傳回 -1。
  • 此方法String getPattern()傳回無效的正規表示式。
此外,繼承的方法String getMessage()會傳回多行字串,其中包含從先前方法傳回的值以及範本中語法錯誤發生位置的可視指示。什麼是語法錯誤?以下是一個範例: 在本例中,我們忘記在嵌套標誌表達式中java RegexDemo (?itree Treehouse 指定右括號元字元 ( )。)這是此錯誤的輸出:
regex = (?itree
input = Treehouse
Неправильное регулярное выражение: Unknown inline modifier near index 3
(?itree
   ^
Описание: Unknown inline modifier
Позиция: 3
Неправильный шаблон: (?itree

使用 Regex API 建立有用的正規表示式應用程式

正規表示式使您能夠創建功能強大的文字處理應用程式。在本節中,我們將向您展示兩個方便的應用程序,希望它們能鼓勵您進一步探索 Regex API 類別和方法。第二個附錄介紹了 Lexan:一個用於執行詞法分析的可重複使用程式碼庫。 Java 中的正規表示式,第 4 - 3 部分

正規表示式和文檔

文件編制是開發專業軟體時的強制性任務之一。幸運的是,正規表示式可以在文件建立的許多方面為您提供幫助。清單 1 中的程式碼從原始檔案中提取包含單行和多行 C 風格註解的行,並將它們寫入另一個檔案。為了使程式碼正常運作,註解必須位於同一行。清單 1. 檢索評論
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

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

public class ExtCmnt
{
   public static void main(String[] args)
   {
      if (args.length != 2)
      {
         System.err.println("Способ применения: java ExtCmnt infile outfile");
         return;
      }

      Pattern p;
      try
      {
         // Следующий шаблон определяет многострочные комментарии,
         // располагающиеся в одной строке (например, /* одна строка */)
            // и однострочные комментарии (например, // Howая-то строка).
            // Комментарий может располагаться в любом месте строки.

         p = Pattern.compile(".*/\\*.*\\*/|.*//.*$");
      }
      catch (PatternSyntaxException pse)
      {
         System.err.printf("Синтаксическая ошибка в регулярном выражении: %s%n", pse.getMessage());
         System.err.printf("Описание ошибки: %s%n", pse.getDescription());
         System.err.printf("Позиция ошибки: %s%n", pse.getIndex());
         System.err.printf("Ошибочный шаблон: %s%n", pse.getPattern());
         return;
      }

      try (FileReader fr = new FileReader(args[0]);
           BufferedReader br = new BufferedReader(fr);
           FileWriter fw = new FileWriter(args[1]);
           BufferedWriter bw = new BufferedWriter(fw))
      {
         Matcher m = p.matcher("");
         String line;
         while ((line = br.readLine()) != null)
         {
            m.reset(line);
            if (m.matches()) /* Должна соответствовать вся строка */
            {
               bw.write(line);
               bw.newLine();
            }
         }
      }
      catch (IOException ioe)
      {
         System.err.println(ioe.getMessage());
         return;
      }
   }
}
清單 1 中的方法main()首先檢查命令列語法是否正確,然後將用於偵測單行和多行註解的正規表示式編譯到類別物件中Pattern。如果沒有引發異常PatternSyntaxException,該方法main()將開啟來源文件,建立目標文件,取得匹配器來匹配根據模式讀取的每一行,然後逐行讀取來源文件。對於每一行,它都與註解模式相符。如果成功,該方法main()會將字串(後跟換行符)寫入目標檔案(我們將在未來的 Java 101 教程中介紹檔案 I/O 邏輯)。如下編譯清單 1: javac ExtCmnt.java 使用檔案作為輸入來執行應用程式ExtCmnt.javajava ExtCmnt ExtCmnt.java out 您應該在檔案輸出中得到以下結果:
// Следующий шаблон определяет многострочные комментарии,
 // располагающиеся в одной строке (например, /* одна строка */)
    // и однострочные комментарии (например, // Howая-то строка).
    // Комментарий может располагаться в любом месте строки.
p = Pattern.compile(".*/\\*.*\\*/|.*//.*$");
    if (m.matches()) /* Должна соответствовать вся строка */
在模式字串 中.*/\\*.*\\*/|.*//.*$,管道元字元|充當邏輯 OR 運算符,指示匹配器應使用給定正規表示式構造的左操作數在匹配器文字中尋找匹配項。如果沒有匹配項,則匹配器將使用給定正則表達式構造中的正確操作數進行另一次搜尋嘗試(捕獲組中的括號元字元也形成邏輯運算符)。 Java 中的正規表示式,第 5 部分
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION