JavaRush /وبلاگ جاوا /Random-FA /عبارات منظم در جاوا (RegEx)

عبارات منظم در جاوا (RegEx)

در گروه منتشر شد
عبارات منظم موضوعی است که برنامه نویسان، حتی برنامه نویسان با تجربه، اغلب آن را به بعد موکول می کنند. با این حال، اکثر توسعه دهندگان جاوا دیر یا زود باید با پردازش متن سر و کار داشته باشند. اغلب - با عملیات جستجو در متن و ویرایش. بدون عبارات منظم، کد برنامه مولد و فشرده مرتبط با پردازش متن به سادگی غیرقابل تصور است. پس از به تعویق انداختن آن دست بردارید، بیایید همین الان با «عادی‌ها» بپردازیم. این کار چندان سختی نیست.

بیان منظم RegEx چیست؟

در واقع یک عبارت منظم (RegEx در جاوا) الگویی برای جستجوی یک رشته در متن است. در جاوا، نمایش اولیه این الگو همیشه یک رشته است، یعنی یک شی از کلاس String. با این حال، هیچ رشته ای را نمی توان در یک عبارت منظم کامپایل کرد، فقط آنهایی که از قوانین نوشتن یک عبارت منظم پیروی می کنند - نحوی که در مشخصات زبان تعریف شده است. برای نوشتن یک عبارت منظم، از کاراکترهای الفبایی و عددی و همچنین متاکاراکترها - کاراکترهایی که معنای خاصی در نحو عبارات منظم دارند، استفاده می شود. مثلا:
String regex = "java"; // string template "java";
String regex = "\\d{3}"; // string template of three numeric characters;

ایجاد عبارات منظم در جاوا

برای ایجاد یک RegEx در جاوا، باید دو مرحله ساده را دنبال کنید:
  1. آن را به عنوان یک رشته با استفاده از نحو عبارت منظم بنویسید.
  2. این رشته را به یک عبارت منظم کامپایل کنید.
کار با عبارات منظم در هر برنامه جاوا با ایجاد یک شی کلاس شروع می شود Pattern. برای انجام این کار، باید یکی از دو متد استاتیک موجود در کلاس را فراخوانی کنید compile. روش اول یک آرگومان را می گیرد - رشته ای از یک عبارت منظم، و دومی - به اضافه پارامتر دیگری که حالت مقایسه الگو با متن را روشن می کند:
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
لیست مقادیر پارامترهای ممکن flagsدر کلاس تعریف شده است Patternو به عنوان متغیرهای کلاس ایستا در دسترس ما است. مثلا:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//searching for matches with the pattern will be done case-insensitively.
در اصل، کلاس Patternیک سازنده عبارت منظم است. در زیر هود، متد compileسازنده خصوصی کلاس را فراخوانی می کند Patternتا یک نمای کامپایل شده ایجاد کند. این روش ایجاد یک نمونه الگو با هدف ایجاد آن به عنوان یک شیء تغییرناپذیر پیاده سازی می شود. هنگام ایجاد، یک بررسی نحوی از عبارت منظم انجام می شود. اگر خطایی در خط وجود داشته باشد، یک استثنا ایجاد می شود PatternSyntaxException.

نحو عبارت منظم

نحو عبارت منظم مبتنی بر استفاده از نمادها است <([{\^-=$!|]})?*+.>که می توانند با کاراکترهای الفبایی ترکیب شوند. بسته به نقش آنها می توان آنها را به چند گروه تقسیم کرد:
1. متاکاراکترها برای تطبیق مرزهای خط یا متن
متاکاراکتر هدف
^ شروع خط
$ آخر خط
\b مرز کلمه
\ B نه محدودیت کلمه
شروع ورودی
\G پایان مسابقه قبلی
\Z پایان ورودی
\z پایان ورودی
2. متاکاراکترها برای جستجوی کلاس های کاراکتر
متاکاراکتر هدف
\d نماد دیجیتال
\ D کاراکتر غیر عددی
\s شخصیت فضایی
\S کاراکتر بدون فضای سفید
\w کاراکتر الفبایی یا زیرخط
\ W هر کاراکتری غیر از حروف الفبا، عددی یا خط زیر
. هر شخصیت
3. متاکاراکترها برای جستجوی نمادهای ویرایش متن
متاکاراکتر هدف
\ t کاراکتر برگه
\n شخصیت خط جدید
\r کاراکتر بازگشت کالسکه
\f رفتن به صفحه جدید
\u0085 کاراکتر خط بعدی
\u 2028 کاراکتر جداکننده خط
\u 2029 نماد جداکننده پاراگراف
4. متاکاراکترها برای گروه بندی شخصیت ها
متاکاراکتر هدف
[a B C] هر یک از موارد فوق (الف، ب یا ج)
[^abc] غیر از موارد ذکر شده (نه a، b، c)
[a-zA-Z] ادغام محدوده (نویسه های لاتین a تا z به حروف بزرگ و کوچک حساس نیستند)
[تبلیغ[mp]] الحاق کاراکترها (a به d و m به p)
[az&&[def]] تقاطع نمادها (نمادهای d,e,f)
[az&&[^bc]] تفریق کاراکترها (شخصیت های a، dz)
5. متاسمبول هایی برای نشان دادن تعداد کاراکترها - کمیت سازها. کمیت همیشه بعد از یک کاراکتر یا گروهی از کاراکترها قرار می گیرد.
متاکاراکتر هدف
? یکی یا گم شده
* صفر یا چند بار
+ یک یا چند بار
{n} n بار
{n،} n بار یا بیشتر
{n,m} نه کمتر از n بار و نه بیشتر از m بار

حالت کمیت حریص

ویژگی خاص کمیت‌فایرها امکان استفاده از آنها در حالت‌های مختلف است: حریص، فوق‌طمع و تنبل. حالت فوق العاده حریص با اضافه کردن علامت " +" بعد از کمیت، و حالت تنبل با افزودن نماد " ?" روشن می شود. مثلا:
"A.+a" // greedy mode
"A.++a" // over-greedy mode
"A.+?a" // lazy mode
با استفاده از این الگو به عنوان مثال، بیایید سعی کنیم بفهمیم که چگونه کمی‌سازها در حالت‌های مختلف کار می‌کنند. به طور پیش فرض، کمیت در حالت حریص کار می کند. این بدان معنی است که به دنبال طولانی ترین تطابق ممکن در رشته است. در نتیجه اجرای این کد:
public static void main(String[] args) {
    String text = "Egor Alla Alexander";
    Pattern pattern = Pattern.compile("A.+a");
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        System.out.println(text.substring(matcher.start(), matcher.end()));
    }
}
ما خروجی زیر را دریافت خواهیم کرد: Alla Alexa الگوریتم جستجو برای یک الگوی داده شده " А.+а" به ترتیب زیر اجرا می شود:
  1. در الگوی داده شده، اولین کاراکتر کاراکتر حرف روسی است А. Matcherآن را با هر کاراکتر متن مطابقت می دهد و از موقعیت صفر شروع می شود. در موقعیت صفر در متن ما یک نماد وجود دارد Е، بنابراین Matcherبه ترتیب از کاراکترهای متن عبور می کند تا زمانی که با الگو مطابقت داشته باشد. در مثال ما، این نماد در موقعیت شماره 5 است.

    عبارات منظم در جاوا - 2
  2. پس از یافتن یک تطابق با کاراکتر اول الگو، Matcherمطابقت را با کاراکتر دوم الگو بررسی می‌کند. در مورد ما، این نماد " ." است که مخفف هر کاراکتری است.

    عبارات منظم در جاوا - 3

    در جایگاه ششم نماد حرف قرار دارد л. البته با الگوی «هر شخصیتی» مطابقت دارد.

  3. Matcherبه بررسی کاراکتر بعدی از الگو می رود. در قالب ما، با استفاده از کمیت " " مشخص شده است .+. از آنجایی که تعداد تکرار "هر کاراکتری" در الگو یک یا چند بار است، Matcherتا زمانی که شرط "هر کاراکتری" وجود داشته باشد، به نوبه خود نویسه بعدی را از رشته می گیرد و آن را برای مطابقت با الگو بررسی می کند. در مثال ما - تا انتهای خط ( از موقعیت شماره 7 - شماره 18 متن).

    عبارات منظم در جاوا - 4

    در واقع، Matcherکل خط را تا انتها ضبط می کند - اینجاست که "طمع" آن خود را نشان می دهد.

  4. پس از Matcherرسیدن به انتهای متن و اتمام بررسی قسمت " А.+" از الگو، Matcher شروع به بررسی بقیه الگو - کاراکتر حرف می‌کند а. از آنجایی که متن در جهت جلو به پایان رسیده است، بررسی در جهت معکوس انجام می شود و از آخرین کاراکتر شروع می شود:

    عبارات منظم در جاوا - 5
  5. Matcherتعداد تکرارهای الگوی " .+" را که به انتهای متن رسیده است، "به خاطر می آورد"، بنابراین تعداد تکرارها را یک بار کاهش می دهد و الگوی متن را بررسی می کند تا زمانی که مطابقت پیدا شود: عبارات منظم در جاوا - 6

حالت کمیت فوق العاده حریص

در حالت فوق العاده حریص، تطبیق مشابه مکانیسم حالت حریص عمل می کند. تفاوت این است که وقتی متن را تا انتهای خط می گیرید، هیچ جستجوی به عقب وجود ندارد. یعنی سه مرحله اول در حالت فوق حریص شبیه حالت حریص خواهد بود. پس از گرفتن کل رشته، تطبیق دهنده بقیه الگو را اضافه می کند و آن را با رشته ضبط شده مقایسه می کند. در مثال ما، هنگام اجرای متد اصلی با الگوی " А.++а"، هیچ منطبقی پیدا نخواهد شد. عبارات منظم در جاوا - 7

حالت کمیت کننده تنبل

  1. در این حالت، در مرحله اولیه، مانند حالت حریص، مطابقت با اولین کاراکتر الگو جستجو می شود:

    عبارات منظم در جاوا - 8
  2. بعد، به دنبال تطابق با کاراکتر بعدی در الگو - هر کاراکتری است:

    عبارات منظم در جاوا - 9
  3. بر خلاف حالت حریص، حالت تنبل کوتاه ترین تطابق را در متن جستجو می کند، بنابراین پس از یافتن تطابق با کاراکتر دوم الگو که با یک نقطه مشخص شده و با کاراکتر در موقعیت شماره 6 متن مطابقت دارد، آن را پیدا می کند. Matcherبررسی خواهد کرد که آیا متن با بقیه الگو مطابقت دارد - کاراکتر " а" .

    عبارات منظم در جاوا - 10
  4. از آنجایی که مطابقت با الگوی متن پیدا نشد (در موقعیت شماره 7 در متن علامت " " وجود دارد лMatcher"هر کاراکتری" دیگری به الگو اضافه می کند، زیرا به عنوان یک یا چند بار مشخص شده است. و دوباره الگو را با متن در موقعیت های شماره 5 تا 8 مقایسه می کند:

    عبارات منظم در جاوا - 11
  5. در مورد ما مطابقت پیدا شد، اما هنوز به انتهای متن نرسیده است. بنابراین، از موقعیت شماره 9، بررسی با جستجوی اولین کاراکتر الگو با استفاده از الگوریتم مشابه آغاز می شود و سپس تا انتهای متن تکرار می شود.

    عبارات منظم در جاوا - 12
در نتیجه روش، mainهنگام استفاده از А.+?аالگوی " "، نتیجه زیر را دریافت خواهیم کرد: Alla Alexa همانطور که از مثال ما مشخص است، هنگام استفاده از حالت های مختلف کمیت برای یک الگو، نتایج متفاوتی دریافت کردیم. بنابراین باید این ویژگی را در نظر گرفت و بسته به نتیجه دلخواه در حین جستجو حالت مورد نظر را انتخاب کرد.

فرار از کاراکترها در عبارات منظم

از آنجایی که یک عبارت منظم در جاوا، یا به طور دقیق‌تر نمایش اولیه آن، با استفاده از یک رشته لفظی مشخص می‌شود، لازم است قوانین مشخصات جاوا را که مربوط به حروف رشته‌ای است، در نظر بگیریم. به طور خاص، کاراکتر بک اسلش " \" در متن های رشته ای در کد منبع جاوا به عنوان یک کاراکتر فرار تعبیر می شود که به کامپایلر هشدار می دهد که کاراکتری که به دنبال آن می آید یک کاراکتر خاص است و باید به روش خاصی تفسیر شود. مثلا:
String s = "The root directory is \nWindows";//wrap Windows to a new line
String s = "The root directory is \u00A7Windows";//insert paragraph character before Windows
بنابراین، در لفظهای رشته ای که یک عبارت منظم را توصیف می کنند و از \کاراکتر " " استفاده می کنند (مثلاً برای متاکراکترها)، باید آن را دو برابر کرد تا کامپایلر بایت کد جاوا آن را به گونه ای متفاوت تفسیر نکند. مثلا:
String regex = "\\s"; // template for searching for space characters
String regex = "\"Windows\""; // pattern to search for the string "Windows"
اگر قصد داریم از آنها به عنوان کاراکترهای "عادی" استفاده کنیم، باید از کاراکتر بک اسلش دوتایی نیز برای فرار از کاراکترهای خاص استفاده شود. مثلا:
String regex = "How\\?"; // template for searching the string "How?"

روش های کلاس الگو

کلاس Patternمتدهای دیگری برای کار با عبارات منظم دارد: String pattern()- نمایش رشته اصلی عبارت منظم را که شی از آن ایجاد شده است، برمی گرداند Pattern:
Pattern pattern = Pattern.compile("abc");
System.out.println(Pattern.pattern())//"abc"
static boolean matches(String regex, CharSequence input)- به شما امکان می دهد عبارت منظم ارسال شده در پارامتر regex را در مقابل متن ارسال شده در پارامتر بررسی کنید input. برمی‌گرداند: true – اگر متن با الگو مطابقت داشته باشد. نادرست - در غیر این صورت؛ مثال:
System.out.println(Pattern.matches("A.+a","Alla"));//true
System.out.println(Pattern.matches("A.+a","Egor Alla Alexander"));//false
int flags()- flagsمقادیر پارامتر الگو را که در زمان ایجاد آن تنظیم شده بود، یا اگر این پارامتر تنظیم نشده بود، 0 را برمی گرداند. مثال:
Pattern pattern = Pattern.compile("abc");
System.out.println(pattern.flags());// 0
Pattern pattern = Pattern.compile("abc",Pattern.CASE_INSENSITIVE);
System.out.println(pattern.flags());// 2
String[] split(CharSequence text, int limit)- متن ارسال شده به عنوان پارامتر را به آرایه ای از عناصر تقسیم می کند String. پارامتر limitحداکثر تعداد منطبقاتی را که در متن جستجو می شوند را تعیین می کند:
  • هنگامی که limit>0- جستجو برای limit-1مسابقات انجام می شود.
  • در limit<0– تمام موارد منطبق در متن را جستجو می کند
  • When limit=0– تمام موارد منطبق را در متن جستجو می کند، در حالی که خطوط خالی در انتهای آرایه حذف می شوند.
مثال:
public static void main(String[] args) {
    String text = "Egor Alla Anna";
    Pattern pattern = Pattern.compile("\\s");
    String[] strings = pattern.split(text,2);
    for (String s : strings) {
        System.out.println(s);
    }
    System.out.println("---------");
    String[] strings1 = pattern.split(text);
    for (String s : strings1) {
        System.out.println(s);
    }
}
خروجی کنسول: Egor Alla Anna -------- Egor Alla Anna روش کلاس دیگری را برای ایجاد یک شی Matcherدر زیر در نظر خواهیم گرفت.

روش های کلاس مطابقت

Matcherکلاسی است که از آن یک شی برای جستجوی الگوها ایجاد می شود. Matcher- این یک "موتور جستجو"، یک "موتور" از عبارات منظم است. برای جستجو، باید دو چیز به او داده شود: یک الگوی جستجو و یک «آدرس» برای جستجو. برای ایجاد یک شی، Matcherمتد زیر در کلاس ارائه می شود Pattern: рublic Matcher matcher(CharSequence input) به عنوان آرگومان، متد دنباله ای از کاراکترها را می گیرد که جستجو در آنها انجام می شود. اینها اشیاء کلاسهایی هستند که رابط را پیاده سازی می کنند CharSequence. Stringشما می توانید نه تنها , بلکه StringBuffer, StringBuilderو به عنوان استدلال Segmentنیز عبور دهید CharBuffer. الگوی جستجو شی کلاسی است Patternکه متد بر روی آن فراخوانی می شود matcher. نمونه ای از ایجاد تطبیق:
Pattern p = Pattern.compile("a*b");// compiled the regular expression into a view
Matcher m = p.matcher("aaaaab");//created a search engine in the text “aaaaab” using the pattern "a*b"
اکنون، با کمک «موتور جستجو» خود، می‌توانیم موارد منطبق را جستجو کنیم، موقعیت مطابقت را در متن پیدا کنیم و متن را با استفاده از متدهای کلاس جایگزین کنیم. این روش boolean find()برای مطابقت بعدی در متن با الگو جستجو می کند. با استفاده از این روش و عملگر حلقه، می توانید کل متن را با توجه به مدل رویداد آنالیز کنید (عملیات لازم را در هنگام رخ دادن یک رویداد انجام دهید - یافتن مطابقت در متن). به عنوان مثال، با استفاده از متدهای این کلاس، int start()می‌توانید int end()موقعیت‌های مطابقت را در متن تعیین کنید و با استفاده از متدها String replaceFirst(String replacement)، String replaceAll(String replacement)مطابقت‌های متن را با متن جایگزین دیگری جایگزین کنید. مثال:
public static void main(String[] args) {
    String text = "Egor Alla Anna";
    Pattern pattern = Pattern.compile("A.+?a");

    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        int start=matcher.start();
        int end=matcher.end();
        System.out.println("Match found" + text.substring(start,end) + " с "+ start + " By " + (end-1) + "position");
    }
    System.out.println(matcher.replaceFirst("Ira"));
    System.out.println(matcher.replaceAll("Olga"));
    System.out.println(text);
}
خروجی برنامه: یک مسابقه پیدا شد Alla از 5 تا 8 موقعیت یک مطابقت پیدا شد آنا از 10 تا 13 موقعیت Egor Ira Anna Egor Olga Olga Egor Alla Anna از مثال مشخص است که روش ها یک شی جدید replaceFirstایجاد می کنند - یک رشته که متن منبعی است که در آن مطابق با الگو با متن ارسال شده به متد به عنوان آرگومان جایگزین می شود. علاوه بر این، روش فقط جایگزین اولین مسابقه و همه موارد در آزمون می شود. متن اصلی بدون تغییر باقی مانده است. استفاده از سایر متدهای کلاس و همچنین نمونه‌هایی از عبارات منظم را می‌توانید در این سری مقالات بیابید . رایج ترین عملیات با عبارات منظم هنگام کار با متن از کلاس ها هستند و در داخل آن تعبیه شده اند . اینها روشهایی مانند , , , . اما در واقع «زیر کاپوت» از و . بنابراین، اگر نیاز به جایگزینی متن یا مقایسه رشته ها در یک برنامه بدون نوشتن کد غیر ضروری دارید، از روش های . اگر به قابلیت های پیشرفته نیاز دارید، به کلاس ها و . replaceAllStringreplaceFirstreplaceAllMatcherPatternMatcherStringsplitmatchesreplaceFirstreplaceAllPatternMatcherStringPatternMatcher

نتیجه

یک عبارت منظم در یک برنامه جاوا با استفاده از رشته هایی که با الگوی تعریف شده توسط قوانین مطابقت دارد، توصیف می شود. هنگامی که کد اجرا می شود، جاوا این رشته را در یک شی کلاس دوباره کامپایل می کند Patternو از شی کلاس Matcherبرای یافتن موارد مطابق در متن استفاده می کند. همانطور که در ابتدا گفتم، عبارات منظم اغلب برای بعداً کنار گذاشته می شوند و موضوعی دشوار در نظر گرفته می شود. با این حال، اگر اصول نحو، فراکاراکترها، فرار کردن، و مطالعه نمونه‌هایی از عبارات منظم را بدانید، آنها بسیار ساده‌تر از آن چیزی هستند که در نگاه اول به نظر می‌رسند.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION