JavaRush /בלוג Java /Random-HE /ביטויים רגולריים ב-Java, חלק 4

ביטויים רגולריים ב-Java, חלק 4

פורסם בקבוצה
אנו מציגים לתשומת לבך תרגום של מדריך קצר לביטויים רגולריים בג'אווה, שנכתב על ידי ג'ף פריזן עבור אתר 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() ( ) ואת המיקום שבו התרחשה שגיאת התחביר. אם המיקום של שגיאת התחביר אינו ידוע, הערך מוגדר ל- . סביר להניח שלעולם לא תצטרך ליצור מופעים של ה- . עם זאת, תצטרך לחלץ את הערכים לעיל בעת יצירת הודעת שגיאה מעוצבת. כדי לעשות זאת, אתה יכול להשתמש בשיטות הבאות: PatternPatternSyntaxException(String desc, String regex, int index)descregexindex-1PatternSyntaxException
  • השיטה 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

בנה יישומי ביטוי רגולרי שימושיים באמצעות ממשק API של Regex

ביטויים רגולריים מאפשרים לך ליצור יישומי עיבוד טקסט רבי עוצמה. בחלק זה, נציג לך שני יישומים שימושיים שבתקווה יעודדו אותך להמשיך ולחקור את המחלקות והשיטות של 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;
      }
   }
}
השיטה main()ברשימה 1 בודקת תחילה תחביר נכון של שורת הפקודה ולאחר מכן קומפילציה של ביטוי רגולרי שנועד לזהות הערות בודדות ומרובות שורות לתוך אובייקט מחלקה Pattern. אם לא הועלה חריג PatternSyntaxException, השיטה main()פותחת את קובץ המקור, יוצרת את קובץ היעד, משיגה התאמה שתתאים לכל שורה שנקראה מול התבנית, ולאחר מכן קוראת את קובץ המקור שורה אחר שורה. עבור כל שורה, הוא מותאם עם דפוס הערה. אם היא מצליחה, השיטה main()כותבת את המחרוזת (אחריה שורה חדשה) לקובץ היעד (אנחנו נסקור את הלוגיקה של ה-I/O של הקובץ במדריך עתידי של Java 101). הרכיב את רשימה 1 באופן הבא: javac ExtCmnt.java הפעל את היישום עם קובץ ExtCmnt.javaכקלט: java ExtCmnt ExtCmnt.java out אתה אמור לקבל את התוצאות הבאות בקובץ החוצה:
// Следующий шаблон определяет многострочные комментарии,
 // располагающиеся в одной строке (например, /* одна строка */)
    // и однострочные комментарии (например, // Howая-то строка).
    // Комментарий может располагаться в любом месте строки.
p = Pattern.compile(".*/\\*.*\\*/|.*//.*$");
    if (m.matches()) /* Должна соответствовать вся строка */
במחרוזת התבנית .*/\\*.*\\*/|.*//.*$, מתא-ה-pipe |פועל כאופרטור OR לוגי, המציין שהמתאים צריך להשתמש באופרנד השמאלי של מבנה הביטוי הרגולרי הנתון כדי למצוא התאמה בטקסט ההתאמה. אם אין התאמות, המתאם משתמש באופרנד הימני ממבנה הביטוי הרגולרי הנתון לניסיון חיפוש נוסף (המתא-תווים בסוגריים בקבוצה שנלכדה יוצרים גם אופרטור לוגי). ביטויים רגולריים ב-Java, חלק 5
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION