ترجمهای از راهنمای کوتاه عبارات منظم در زبان جاوا را که توسط جف فریسن برای وبسایت
JavaWorld نوشته شده است، مورد توجه شما قرار میدهیم . برای سهولت در مطالعه مقاله را به چند قسمت تقسیم کرده ایم.
استفاده از Regular Expression API در برنامه های جاوا برای تشخیص و توصیف الگوها
کاراکتر جاوا و انواع دادههای رشتهای مختلف، پشتیبانی سطح پایینی را برای تطبیق الگو فراهم میکنند، اما استفاده از آنها برای این منظور معمولاً پیچیدگی کد قابل توجهی را اضافه میکند. کد ساده تر و کارآمدتر با استفاده از Regex API ("Regular Expression API") به دست می آید. این آموزش به شما کمک می کند تا با عبارات منظم و Regex API شروع کنید. ما ابتدا در مورد سه کلاس جالب در بسته به طور کلی بحث خواهیم کرد
java.util.regex
، و سپس نگاهی به داخل کلاس بیندازیم
Pattern
و ساختارهای تطبیق الگوی پیچیده آن را بررسی خواهیم کرد.
توجه: می توانید کد منبع (ایجاد شده توسط جف فریسن برای سایت JavaWorld) برنامه آزمایشی را از این مقاله
از اینجا دانلود کنید .
عبارات منظم چیست؟
یک عبارت منظم (به طور منظم عبارت/regex/regexp) رشته ای است که الگویی است که مجموعه خاصی از رشته ها را توصیف می کند. الگو تعیین می کند که کدام ردیف ها به مجموعه تعلق دارند. این الگو متشکل از لفظ ها و فراکاراکترها است - شخصیت هایی با معنای خاص به جای معنای تحت اللفظی. تطبیق الگو جستجوی متن برای یافتن موارد منطبق است، یعنی رشته هایی که با الگوی عبارت منظم مطابقت دارند. جاوا از تطبیق الگو از طریق Regex API خود پشتیبانی می کند. این API از سه کلاس تشکیل شده است:
Pattern
,
Matcher
و
PatternSyntaxException
واقع در بسته
java.util.regex
:
- اشیاء کلاس
Pattern
، که قالب نیز نامیده می شوند، عبارات منظم کامپایل شده هستند.
- اشیاء کلاس
Matcher
یا تطبیقکنندهها، مکانیسمهای تفسیر الگو برای یافتن تطابق در دنبالههای کاراکتر هستند (اشیایی که کلاسهای آنها یک رابط را پیادهسازی میکنند java.lang.CharSequence
و به عنوان منابع متنی عمل میکنند).
- اشیاء کلاس
PatternSyntaxException
برای توصیف الگوهای عبارت منظم نامعتبر استفاده می شود.
جاوا همچنین از تطبیق الگو از طریق روش های مختلف پشتیبانی می کند
java.lang.String
. برای مثال، تابع تنها در صورتی
boolean matches (String regex)
برمی گردد
true
که رشته فراخوان دقیقاً با عبارت معمولی مطابقت داشته باشد
regex
.
روش های راحت |
matches() و سایر روشهای راحت مبتنی بر بیان منظم کلاس String به روشی مشابه Regex API در زیر هود پیادهسازی میشوند. |
RegexDemo
من یک برنامه برای نشان دادن عبارات منظم جاوا و
RegexDemo
متدهای مختلف ایجاد کردم
Pattern
. در زیر کد منبع این برنامه آزمایشی آمده است. فهرست 1. نمایش عبارت منظم
Matcher
PatternSyntaxException
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class RegexDemo
{
public static void main(String[] args)
{
if (args.length != 2)
{
System.err.println("usage: java RegexDemo regex input");
return;
}
args[1] = args[1].replaceAll("\\\\n", "\n");
try
{
System.out.println("regex = " + args[0]);
System.out.println("input = " + args[1]);
Pattern p = Pattern.compile(args[0]);
Matcher m = p.matcher(args[1]);
while (m.find())
System.out.println("Found [" + m.group() + "] starting at "
+ m.start() + " and ending at " + (m.end() - 1));
}
catch (PatternSyntaxException pse)
{
System.err.println("Неправильное регулярное выражение: " + pse.getMessage());
System.err.println("Описание: " + pse.getDescription());
System.err.println("Позиция: " + pse.getIndex());
System.err.println("Неправильный шаблон: " + pse.getPattern());
}
}
}
اولین کاری که یک متد
main
کلاس انجام می دهد
RegexDemo
، بررسی خط فرمان آن است. به دو آرگومان نیاز دارد: اولی یک عبارت منظم و دومی متن ورودی است که عبارت منظم در آن جستجو می شود. ممکن است لازم باشد از یک کاراکتر خط جدید در متن ورودی استفاده کنید
(\n)
.
\
این کار فقط با مشخص کردن کاراکتر به دنبال آن کاراکتر انجام می شود
n
. تابع
main()
این دنباله کاراکتر را به مقدار یونیکد 10 تبدیل می
کند . بلوک ابتدا عبارت منظم داده شده و متن ورودی را خروجی می دهد و سپس یک شی ایجاد می کند که عبارت منظم کامپایل شده را ذخیره می کند (عبارات منظم برای بهبود عملکرد تطبیق الگو کامپایل می شوند). یک تطبیق از شی استخراج می شود و برای جستجوی مکرر منطبقات استفاده می شود تا زمانی که همه آنها پیدا شوند. بلوک چندین متد کلاس را برای بازیابی اطلاعات مفید در مورد استثنا فراخوانی می کند. این اطلاعات به صورت متوالی به جریان خروجی خروجی می شود. هنوز نیازی به دانستن جزئیات نحوه عملکرد کد نیست: زمانی که API را در قسمت دوم مقاله مطالعه کنیم، مشخص خواهند شد. با این حال، باید لیست 1 را کامپایل کنید. کد را از لیست 1 بگیرید و سپس دستور زیر را در خط فرمان برای کامپایل تایپ کنید :
RegexDemo
try-catch
try
Pattern
Pattern
catch
PatternSyntaxException
RegexDemo
javac RegexDemo.java
کلاس Pattern و ساختارهای آن
کلاس
Pattern
، اولین کلاس از سه کلاسی که Regex API را تشکیل میدهند، یک نمایش کامپایلشده از یک عبارت منظم است. مستندات کلاس SDK
Pattern
انواع ساختارهای عبارات منظم را توصیف می کند، اما اگر به طور فعال از عبارات منظم استفاده نکنید، ممکن است بخش هایی از این مستندات گیج کننده باشد. کمیت سازها چیست و تفاوت بین کمی سازهای حریص، اکراه کننده و تملک در چیست؟ کلاس های کاراکتر، تطبیق مرزها، ارجاعات به عقب و عبارات پرچم جاسازی شده چیست؟ در بخش های بعدی به این سؤالات و سؤالات دیگر پاسخ خواهم داد.
رشته های تحت اللفظی
ساده ترین ساختار عبارت منظم یک رشته تحت اللفظی است. برای موفقیت آمیز بودن تطبیق الگو، بخشی از متن ورودی باید با الگوی آن ساختار مطابقت داشته باشد. مثال زیر را در نظر بگیرید: در این مثال، ما سعی میکنیم برای یک الگو در متن ورودی
java RegexDemo apple applet
مطابقت پیدا کنیم . نتیجه زیر مسابقه یافت شده را نشان می دهد:
apple
applet
regex = apple
input = applet
Found [apple] starting at 0 and ending at 4
در خروجی عبارت منظم و متن ورودی و سپس نشانه ای از تشخیص موفقیت آمیز
apple
در اپلت را می بینیم. علاوه بر این، موقعیت های شروع و پایان این مسابقه به ترتیب:
0
و
4
. موقعیت شروع نشان دهنده اولین مکان در متن است که در آن مسابقه پیدا شده است و موقعیت پایان نشان دهنده آخرین نقطه مسابقه است. حالا فرض کنید خط فرمان زیر را داده ایم:
java RegexDemo apple crabapple
این بار نتیجه زیر را با موقعیت های مختلف شروع و پایان دریافت می کنیم:
regex = apple
input = crabapple
Found [apple] starting at 4 and ending at 8
در غیر این صورت، با و
applet
به عنوان عبارت منظم
apple
- متن ورودی، هیچ منطبقی پیدا نخواهد شد. کل عبارت منظم باید مطابقت داشته باشد، اما در این مورد، متن ورودی حاوی
t
پس از
apple
.
متا شخصیت ها
ساختارهای عبارت منظم جالب تر، نویسه های تحت اللفظی را با متاکاراکترها ترکیب می کنند. به عنوان مثال، در یک عبارت منظم
a.b
، متاکاراکتر نقطه
(.)
به معنای هر کاراکتری بین
a
و b است. مثال زیر را در نظر بگیرید:
java RegexDemo .ox "The quick brown fox jumps over the lazy ox."
این مثال
.ox
هم به عنوان یک عبارت منظم و هم
The quick brown fox jumps over the lazy ox.
به عنوان متن ورودی استفاده می کند.
RegexDemo
متن را برای مطابقت هایی جستجو می کند که با هر کاراکتری شروع می شود و به آن ختم می شود
ox.
نتایج اجرای آن به شرح زیر است:
regex = .ox
input = The quick brown fox jumps over the lazy ox.
Found [fox] starting at 16 and ending at 18
Found [ ox] starting at 39 and ending at 41
در خروجی دو تطبیق می بینیم:
fox
and
ox
(با یک کاراکتر فاصله در جلوی آن). متاکاراکتر در مورد اول
.
با یک کاراکتر و در مورد دوم با یک فاصله مطابقت دارد . اگر آن را با یک متاکاراکتر
f
جایگزین کنید چه اتفاقی می افتد ؟ یعنی چیزی که در نتیجه خط فرمان زیر به دست می آوریم: از آنجایی که متاکاراکتر نقطه با هر کاراکتری مطابقت دارد، منطبقات یافت شده برای همه کاراکترها (شامل کاراکتر نقطه انتهایی) متن ورودی را به دست می دهد:
.ox
.
java RegexDemo . "The quick brown fox jumps over the lazy ox."
RegexDemo
regex = .
input = The quick brown fox jumps over the lazy ox.
Found [T] starting at 0 and ending at 0
Found [h] starting at 1 and ending at 1
Found [e] starting at 2 and ending at 2
Found [ ] starting at 3 and ending at 3
Found [q] starting at 4 and ending at 4
Found [u] starting at 5 and ending at 5
Found [i] starting at 6 and ending at 6
Found [c] starting at 7 and ending at 7
Found [k] starting at 8 and ending at 8
Found [ ] starting at 9 and ending at 9
Found [b] starting at 10 and ending at 10
Found [r] starting at 11 and ending at 11
Found [o] starting at 12 and ending at 12
Found [w] starting at 13 and ending at 13
Found [n] starting at 14 and ending at 14
Found [ ] starting at 15 and ending at 15
Found [f] starting at 16 and ending at 16
Found [o] starting at 17 and ending at 17
Found [x] starting at 18 and ending at 18
Found [ ] starting at 19 and ending at 19
Found [j] starting at 20 and ending at 20
Found [u] starting at 21 and ending at 21
Found [m] starting at 22 and ending at 22
Found [p] starting at 23 and ending at 23
Found [s] starting at 24 and ending at 24
Found [ ] starting at 25 and ending at 25
Found [o] starting at 26 and ending at 26
Found [v] starting at 27 and ending at 27
Found [e] starting at 28 and ending at 28
Found [r] starting at 29 and ending at 29
Found [ ] starting at 30 and ending at 30
Found [t] starting at 31 and ending at 31
Found [h] starting at 32 and ending at 32
Found [e] starting at 33 and ending at 33
Found [ ] starting at 34 and ending at 34
Found [l] starting at 35 and ending at 35
Found [a] starting at 36 and ending at 36
Found [z] starting at 37 and ending at 37
Found [y] starting at 38 and ending at 38
Found [ ] starting at 39 and ending at 39
Found [o] starting at 40 and ending at 40
Found [x] starting at 41 and ending at 41
Found [.] starting at 42 and ending at 42
نقل قول متاکاراکترها |
برای مشخص کردن . یا هر متاکاراکتر دیگری به عنوان یک کاراکتر تحت اللفظی در ساختار عبارت منظم، باید به یکی از روش های زیر از آن فرار کنید:
- قبل از آن یک کاراکتر بک اسلش قرار دهید.
- این متاکاراکتر را بین
\Q و \E (به عنوان مثال، \Q.\E ) قرار دهید.
به یاد داشته باشید که هر کاراکتری را که به صورت تحت اللفظی رشته ظاهر می شود، کپی کنید، مانند String regex = "\\."; بک اسلش (به عنوان مثال، \\. یا \\Q.\\E ). آن دسته از بک اسلش هایی که بخشی از آرگومان خط فرمان هستند را کپی نکنید. |
کلاس های شخصیت
گاهی اوقات شما باید مطابقت های مورد نظر خود را به مجموعه خاصی از شخصیت ها محدود کنید. به عنوان مثال، متن را برای حروف صدادار،،، و، جستجو کنید
a
، با اینکه
e
هر یک از حروف صدادار مطابقت دارد. در حل چنین مسائلی، کلاسهای کاراکتری به ما کمک میکنند که مجموعهای از کاراکترها را بین متاکاراکترهای براکتهای مربع ( ) تعریف میکنند. این کلاس از کلاس های کاراکتر ساده، کلاس های محدوده، معکوس، اتحاد، تقاطع و کلاس های تفریق پشتیبانی می کند. اکنون همه آنها را بررسی خواهیم کرد.
i
o
u
[ ]
Pattern
کلاس های شخصیت های ساده
یک کلاس کاراکتر ساده شامل کاراکترهایی است که در کنار هم قرار گرفته اند و فقط با آن کاراکترها مطابقت دارد. به عنوان مثال، کلاس با
[abc]
کاراکترها مطابقت دارد و . مثال زیر را در نظر بگیرید: همانطور که از نتایج می بینید، در این مثال فقط کاراکتری که برای آن مطابقت دارد در :
a
b
c
java RegexDemo [csw] cave
c
cave
regex = [csw]
input = cave
Found [c] starting at 0 and ending at 0
کلاس های کاراکتر معکوس
یک کلاس کاراکتر معکوس با یک متاکاراکتر شروع می شود
^
و فقط با کاراکترهایی مطابقت دارد که در آن موجود نیستند. به عنوان مثال، کلاس
[^abc]
با تمام کاراکترها به جز
a
،
b
و مطابقت دارد
c
. مثال زیر را در نظر بگیرید:
java RegexDemo "[^csw]" cave
توجه داشته باشید که در سیستم عامل من (ویندوز) دو نقل قول لازم است زیرا پوسته آنها را
^
به عنوان یک کاراکتر فرار در نظر می گیرد. همانطور که می بینید، در این مثال فقط کاراکترهای
a
و پیدا شدند که برای آنها مطابقت دارد در :
v
e
cave
regex = [^csw]
input = cave
Found [a] starting at 1 and ending at 1
Found [v] starting at 2 and ending at 2
Found [e] starting at 3 and ending at 3
محدوده کلاس های شخصیت
یک کلاس کاراکتر محدوده شامل دو کاراکتر است که با خط فاصله (
-
) از هم جدا شده اند. همه کاراکترها، از کاراکتر سمت چپ خط تیره شروع و با کاراکتر سمت راست ختم میشوند، بخشی از محدوده هستند. به عنوان مثال، محدوده
[a-z]
با تمام حروف کوچک لاتین مطابقت دارد. این معادل تعریف یک کلاس ساده است
[abcdefghijklmnopqrstuvwxyz]
. مثال زیر را در نظر بگیرید:
java RegexDemo [a-c] clown
این مثال فقط با شخصیتی مطابقت دارد
c
که در
clown
:
regex = [a-c]
input = clown
Found [c] starting at 0 and ending at 0
عبارات با قاعده در جاوا قسمت 2 عبارات با قاعده در جاوا قسمت 3 عبارات با قاعده در جاوا قسمت 4 عبارات منظم در جاوا قسمت 5
GO TO FULL VERSION