Diqqətinizə Ceff Friesen tərəfindən javaworld veb-saytı üçün yazılmış Java-da müntəzəm ifadələrə dair qısa bələdçinin tərcüməsini təqdim edirik . Oxumaq asanlığı üçün məqaləni bir neçə hissəyə ayırdıq.
Java-da müntəzəm ifadələr, 1-ci hissə
Çoxlu diapazonların birləşdirilməsi |
Siz bir neçə diapazonu yan-yana yerləşdirməklə tək diapazonlu simvol sinfində birləşdirə bilərsiniz. Məsələn, sinif [a-zA-Z] bütün Latın əlifbası simvollarına kiçik və ya böyük hərflərlə uyğun gəlir. |
Çoxlu diapazonların birləşdirilməsi
Siz bir neçə diapazonu yan-yana yerləşdirməklə tək diapazonlu simvol sinfində birləşdirə bilərsiniz. Məsələn, sinif
[a-zA-Z]
bütün Latın əlifbası simvollarına kiçik və ya böyük hərflərlə uyğun gəlir.
Xarakter Siniflərinin Birləşdirilməsi
Xarakter sinfi birliyi bir neçə iç-içə xarakter sinfindən ibarətdir və nəticədə yaranan birləşmədəki bütün simvollara uyğun gəlir. Məsələn, sinif -dən -ə və -dən -ə qədər
[a-d[m-p]]
olan simvollara uyğun gəlir . Aşağıdakı nümunəyə nəzər salın: Bu nümunədə uyğunluqlar olan , , və , simvollarını tapacaq :
a
d
m
p
java RegexDemo [ab[c-e]] abcdef
a
b
c
d
e
abcdef
regex = [ab[c-e]]
input = abcdef
Found [a] starting at 0 and ending at 0
Found [b] starting at 1 and ending at 1
Found [c] starting at 2 and ending at 2
Found [d] starting at 3 and ending at 3
Found [e] starting at 4 and ending at 4
Simvol sinfinin kəsişməsi
Simvol siniflərinin kəsişməsi bütün iç-içə siniflər üçün ümumi simvollardan ibarətdir və yalnız ümumi simvollara uyğun gəlir. Məsələn, sinif
[a-z&&[d-f]]
simvollara uyğun gəlir
d
və
e
.
f
Aşağıdakı nümunəyə nəzər salın:
java RegexDemo "[aeiouy&&[y]]" party
Qeyd edək ki, mənim Windows əməliyyat sistemimdə ikiqat dırnaq işarəsi tələb olunur, çünki əmr qabığı onları
&
əmr ayırıcısı kimi qəbul edir.
y
Bu nümunə yalnız uyğunluğu olan simvolu tapacaq
party
:
regex = [aeiouy&&[y]]
input = party
Found [y] starting at 4 and ending at 4
Xarakter siniflərinin çıxarılması
Çıxarılan simvol sinifləri iç-içə simvol siniflərində olanlardan başqa bütün simvollardan ibarətdir və yalnız qalan simvollara uyğun gəlir. Məsələn, sinif -dən -ə və -dən -ə
[a-z&&[^m-p]]
olan simvollara uyğun gəlir : Bu nümunədə uyğunluqlar olan simvolları tapacaq :
a
l
q
z
java RegexDemo "[a-f&&[^a-c]&&[^e]]" abcdefg
d
f
abcdefg
regex = [a-f&&[^a-c]&&[^e]]
input = abcdefg
Found [d] starting at 3 and ending at 3
Found [f] starting at 5 and ending at 5
Əvvəlcədən təyin edilmiş xarakter sinifləri
Bəzi simvol sinifləri stenoqrafiya qeydinin istifadəsini əsaslandırmaq üçün
müntəzəm ifadələrdə kifayət qədər tez-tez görünür . Sinif
Pattern
bu cür abbreviaturalar kimi əvvəlcədən təyin edilmiş xarakter siniflərini təklif edir. Onlardan müntəzəm ifadələrinizi sadələşdirmək və sintaksis səhvlərini minimuma endirmək üçün istifadə edə bilərsiniz. Əvvəlcədən təyin edilmiş simvol siniflərinin bir neçə kateqoriyası var: standart, POSIX
java.lang.Character
və skript, blok, kateqoriya və binar kimi Unicode xassələri. Aşağıdakı siyahı yalnız standart siniflərin kateqoriyasını göstərir:
\d
: Nömrə. Ekvivalent [0-9]
.
\D
: Qeyri-rəqəm simvolu. Ekvivalent [^0-9]
.
\s
: Boşluq simvolu. Ekvivalent [ \t\n\x0B\f\r]
.
\S
: Boşluq simvolu deyil. Ekvivalent [^\s]
.
\w
: Söz əmələ gətirən simvol. Ekvivalent [a-zA-Z_0-9]
.
\W
: Söz əmələ gətirən simvol deyil. Ekvivalent [^\w]
.
Aşağıdakı nümunə,
\w
daxil edilmiş mətndəki bütün söz simvollarını təsvir etmək üçün əvvəlcədən təyin edilmiş simvol sinfindən istifadə edir:
java RegexDemo \w "aZ.8 _"
Nöqtə və boşluq simvollarının söz simvolu hesab edilmədiyini göstərən aşağıdakı icra nəticələrinə diqqətlə baxın:
regex = \w
input = aZ.8 _
Found [a] starting at 0 and ending at 0
Found [Z] starting at 1 and ending at 1
Found [8] starting at 3 and ending at 3
Found [_] starting at 5 and ending at 5
Xətt ayırıcıları |
Sinif SDK sənədləri Pattern nöqtə metaxarakterini sətir ayırıcılarından (sətrin sonunu qeyd edən bir və ya iki simvoldan ibarət ardıcıllıqlar) başqa hər hansı simvola uyğun gələn əvvəlcədən təyin edilmiş simvol sinfi kimi təsvir edir. İstisna nöqtələr rejimidir (bunu bundan sonra müzakirə edəcəyik), burada nöqtələr də xətt ayırıcılarına uyğun gəlir. Sinif Pattern aşağıdakı sətir ayırıcılarını fərqləndirir:
- karetanın qaytarılması simvolu (
\r );
- yeni sətir simvolu (kağızın bir sətir irəliləməsi üçün simvol) (
\n );
- dərhal sonra yeni sətir simvolu (
\r\n );
- növbəti sətir simvolu (
\u0085 );
- sətir ayırıcı simvol (
\u2028 );
- paraqraf ayırıcı simvolu (
\u2029 )
|
Tutulan qruplar
Çəkmə qrupu nümunə üzrə axtarış zamanı tapılmış simvol dəstini sonrakı istifadə üçün saxlamaq üçün istifadə olunur. Bu konstruksiya mötərizə ( ) ilə meta-simvollara daxil edilmiş simvollar ardıcıllığıdır
( )
. Nümunə ilə axtarış zamanı tutulan qrupdakı bütün simvollar vahid bütöv hesab olunur. Məsələn, tutma qrupu ( ) , və hərflərini vahid
Java
vahiddə birləşdirir . Bu tutma qrupu daxil edilmiş mətndə nümunənin bütün baş vermələrini tapır . Hər uyğunlaşma ilə əvvəlki saxlanılan simvollar növbəti simvollarla əvəz olunur. Tutulan qruplar digər tutulan qruplar içərisində yerləşə bilər. Məsələn, müntəzəm ifadədə bir qrup bir qrupun içərisinə yerləşdirilir . Hər bir yuvalanmış və ya iç-içə olmayan tutma qrupuna 1-dən başlayaraq nömrə təyin edilir və nömrələmə soldan sağa keçir. Əvvəlki misalda uyğunluqlar 1 nömrəli qrup tutma və 2 nömrəli qrup tutma uyğunluğu . Normal ifadədə 1 nömrəli qrup tutma və 2 nömrəli qrup tutma uyğunluğu . Tutma qrupları tərəfindən saxlanılan uyğunluqlara daha sonra arxa istinadlardan istifadə etməklə daxil olmaq olar. Əsir alınan qrupun nömrəsinə uyğun gələn rəqəmsal simvolun ardınca əks xətt işarəsi kimi göstərilən geri istinad sizə qrup tərəfindən çəkilmiş mətndəki simvollara istinad etməyə imkan verir. Geri keçidə malik olmaq, uyğunlaşdırıcının ələ keçirilən qrupun saxlanmış axtarış nəticələrinə ondan gələn nömrə əsasında istinad etməsinə və sonra növbəti axtarışa cəhd etmək üçün həmin nəticədəki simvollardan istifadə etməsinə səbəb olur. Aşağıdakı misal mətndəki qrammatik səhvləri tapmaq üçün arxa istinaddan istifadəni göstərir: Bu nümunə daxil edilmiş mətndə dərhal sonra gələn dublikat sözü olan qrammatik xətanı tapmaq üçün müntəzəm ifadədən istifadə edir . Bu müntəzəm ifadə tutmaq üçün iki qrup təyin edir: 1 nömrə - , uyğun və 2 nömrə , boşluq simvoluna uyğun gəlir . Arxa istinad 2 nömrəli qrupun saxlanmış nəticəsini yenidən nəzərdən keçirməyə imkan verir ki, uyğunlaşdırıcı boşluqun ilk dəfə baş verməsindən dərhal sonra və ardınca gələn boşluğun ikinci halını axtara bilsin . Qarşılaşmanın nəticələri aşağıdakı kimidir:
J
a
v
a
Java
Java
(Java( language))
(language)
(Java)
(Java( language))
(language)
(a)(b)
(a)
(b)
java RegexDemo "(Java( language)\2)" "The Java language language"
(Java( language)\2)
language
Java
"The Java language language"
(Java( language)\2)
Java language language
(language)
language
\2
language
language
RegexDemo
regex = (Java( language)\2)
input = The Java language language
Found [Java language language] starting at 4 and ending at 25
Sərhəd uyğunlaşdırıcıları
Bəzən xəttin əvvəlində, söz sərhədlərində, mətnin sonunda və s.
Pattern
Bunu aşağıdakı yerlərdə uyğunluqları axtaran müntəzəm ifadə konstruksiyaları olan sinif kənar uyğunlaşdırıcılarından birini istifadə etməklə edə bilərsiniz :
^
: Xəttin başlanğıcı;
$
: Xəttin sonu;
\b
: Söz sərhədi;
\B
: Pseudoword sərhədi;
\A
: mətnin başlanğıcı;
\G
: Əvvəlki matçın sonu;
\Z
: Mətnin sonu, arxa sətir ayırıcı istisna olmaqla (əgər varsa);
\z
: Mətnin sonu
Aşağıdakı misalda , sonra sıfır və ya daha çox söz simvolu ilə
^
başlayan sətirləri tapmaq üçün sərhəd uyğunlaşdırıcı metaxarakteri istifadə edir: Simvol müəyyən edir ki , daxil edilmiş mətnin ilk üç simvolu ardıcıl nümunə simvolları və ardınca istənilən nömrə ilə uyğunlaşdırıla bilər . söz əmələ gətirən simvollardan ibarətdir. Budur icranın nəticəsi:
The
java RegexDemo "^The\w*" Therefore
^
T
h
e
regex = ^The\w*
input = Therefore
Found [Therefore] starting at 0 and ending at 8
Komanda xəttini dəyişdirsəniz nə olar
java RegexDemo "^The\w*" " Therefore"
? Heç bir uyğunluq tapılmayacaq, çünki
Therefore
daxil edilmiş mətndən əvvəl boşluq işarəsi var.
Sıfır uzunluq uyğun gəlir
Bəzən kənar uyğunlaşdırıcılarla işləyərkən sıfır uzunluqlu uyğunluqlarla qarşılaşacaqsınız.
Совпадение нулевой длины
heç bir simvol ehtiva etməyən uyğunluqdur. Onlar boş daxil edilən mətndə, daxil edilən mətnin əvvəlində, daxil edilən mətnin sonuncu simvolundan sonra və daxil olan mətnin istənilən iki simvolu arasında baş verə bilər. Sıfır uzunluqlu matçları tanımaq asandır, çünki onlar həmişə eyni mövqedə başlayır və bitir. Aşağıdakı nümunəyə nəzər salın:
java RegExDemo \b\b "Java is"
Bu nümunə iki ardıcıl söz sərhədini axtarır və nəticələr belə görünür:
regex = \b\b
input = Java is
Found [] starting at 0 and ending at -1
Found [] starting at 4 and ending at 3
Found [] starting at 5 and ending at 4
Found [] starting at 7 and ending at 6
Nəticələrdə bir neçə sıfır uzunluqlu matç görürük. Buradakı son mövqelər başlanğıc mövqelərdən bir azdır, çünki
RegexDemo
mən Siyahı 1-də mənbə kodunda qeyd etmişəm
end() – 1
.
Kəmiyyət göstəriciləri
Kəmiyyət göstəricisi nümunəni rəqəmsal dəyərlə açıq və ya gizli şəkildə əlaqələndirən müntəzəm ifadə konstruksiyasıdır. Bu ədədi dəyər nümunənin neçə dəfə axtarılacağını müəyyənləşdirir. Kəmiyyət göstəriciləri acgöz, tənbəl və super acgözlərə bölünür:
- Acgöz kəmiyyət göstəricisi (
?
, *
və ya +
) ən uzun uyğunluğu tapmaq üçün nəzərdə tutulmuşdur. soruşa bilərəm X
? bir və ya daha az hadisəni tapmaq X
, X*
sıfır və ya daha çox hadisəni tapmaq X
, bir və X+
ya bir neçə hadisəni tapmaq X
, hadisələri X{n}
tapmaq , ən azı (və bəlkə də daha çox) hadisələri tapmaq və ən azı , lakin daha çox deyil .n
X
X{n,}
n
X
X{n,m}
n
m
X
- Tənbəl kəmiyyət göstəricisi (
??
, *?
və ya +?
) ən qısa uyğunluğu tapmaq üçün nəzərdə tutulmuşdur. X??
Bir və ya daha az halı axtarmaq üçün X
, X*
? sıfır və ya daha çox hadisəni tapmaq X
, X+?
bir və ya bir neçə hadisəni tapmaq X
, hadisələri X{n}?
tapmaq , ən azı (və bəlkə də daha çox) hadisələri tapmaq və ən azı , lakin çox olmayan hadisələri tapmaq .n
X
X{n,}?
n
X
X{n,m}?
n
m
X
- Super acgöz kəmiyyət göstəricisi (
?+
, *+
və ya ++
) acgöz kəmiyyət göstəricisinə bənzəyir, istisna olmaqla, super acgöz kəmiyyət göstəricisi ən uzun uyğunluğu tapmaq üçün yalnız bir cəhd edir, acgöz kəmiyyət göstəricisi isə bir neçə cəhd edə bilər. X?+
Bir və ya daha az hadisəni tapmaq X
, X*+
sıfır və ya daha çox hadisəni tapmaq X
, X++
bir və ya bir neçə hadisəni tapmaq X
, hadisələri X{n}+
tapmaq , ən azı (və bəlkə də daha çox) hadisələri tapmaq və ən azı , lakin çox olmayan hadisələri tapmaq üçün təyin edilə bilər. .n
X
X{n,}+
n
X
X{n,m}+
n
m
X
Aşağıdakı misal acgöz kəmiyyət göstəricisinin istifadəsini göstərir:
java RegexDemo .*ox "fox box pox"
Budur nəticələr:
regex = .*ox
input = fox box pox
Found [fox box pox] starting at 0 and ending at 10
Acgöz kəmiyyət göstəricisi (
.*
) ilə bitən simvolların ən uzun ardıcıllığını tapır
ox
. O, bütün daxil edilmiş mətni istehlak edir və sonra daxil edilmiş mətnin bu simvollarla bitdiyini aşkarlayana qədər geri çəkilir. İndi tənbəl kəmiyyət göstəricisinə baxaq:
java RegexDemo .*?ox "fox box pox"
Onun nəticələri:
regex = .*?ox
input = fox box pox
Found [fox] starting at 0 and ending at 2
Found [ box] starting at 3 and ending at 6
Found [ pox] starting at 7 and ending at 10
Tənbəl kəmiyyət göstəricisi (
.*?
) ilə bitən simvolların ən qısa ardıcıllığını tapır
ox
. Boş bir sətirlə başlayır və uyğunluq tapana qədər simvolları tədricən istehlak edir. Və sonra daxil edilən mətn tükənənə qədər işləməyə davam edir. Nəhayət, super acgöz kəmiyyət göstəricisinə baxaq:
java RegexDemo .*+ox "fox box pox"
Və onun nəticələri:
regex = .*+ox
input = fox box pox
Əlavə acgöz kəmiyyət göstəricisi (
.*+
) uyğunluq tapmır, çünki o, bütün daxil edilmiş mətni istehlak edir və
ox
müntəzəm ifadənin sonunda uyğunlaşacaq heç nə qalmır. Acgöz kəmiyyət göstəricisindən fərqli olaraq, super acgöz kəmiyyət göstəricisi geri çəkilmir.
Sıfır uzunluq uyğun gəlir
Bəzən kəmiyyət göstəriciləri ilə işləyərkən sıfır uzunluqlu uyğunluqlarla qarşılaşacaqsınız. Məsələn, aşağıdakı acgöz kəmiyyət göstəricisindən istifadə çoxlu sıfır uzunluqlu uyğunluqlarla nəticələnir:
java RegexDemo a? abaa
Bu nümunənin icrasının nəticələri:
regex = a?
input = abaa
Found [a] starting at 0 and ending at 0
Found [] starting at 1 and ending at 0
Found [a] starting at 2 and ending at 2
Found [a] starting at 3 and ending at 3
Found [] starting at 4 and ending at 3
İcra nəticələrində beş matç var.
a
Birinci, üçüncü və dördüncü olduqca gözlənilsə də (onlar üç hərfin mövqelərinə uyğundur
abaa
), ikinci və beşinci sizi təəccübləndirə bilər. Sanki mətnin sonuna nə
a
uyğun gəldiyini göstərirlər , amma əslində belə deyil.
b
Normal ifadə mətnin sonunda
a?
axtarış aparmır .
b
Varlığı və ya yoxluğu axtarır
a
. Tapmadıqda
a?
,
a
onu sıfır uzunluqlu uyğunluq kimi bildirir.
Daxili bayraq ifadələri
Uyğunlaşdırıcılar nizamlı ifadəni nümunəyə çevirərkən ləğv edilə bilən bəzi standart fərziyyələr irəli sürürlər. Bu məsələni daha sonra müzakirə edəcəyik. Müntəzəm ifadə daxili bayraq ifadəsindən istifadə edərək defoltlardan hər hansı birini ləğv etməyə imkan verir. Bu müntəzəm ifadə quruluşu sual işarəsi metaxarakteri ( ) ətrafında mötərizələrin meta-xarakteri kimi təyin olunur
?
, ardınca kiçik Latın hərfi gəlir. Sinif
Pattern
aşağıdakı iç içə bayraq ifadələrini başa düşür:
(?i)
: böyük hərflərə həssas olmayan nümunə uyğunlaşdırılmasını aktivləşdirir. Məsələn, əmrdən istifadə edərkən java RegexDemo (?i)tree Treehouse
simvolların ardıcıllığı Tree
nümunəyə uyğun gəlir tree
. Defolt hərflərə həssas nümunə axtarışıdır.
(?x)
: Nümunə daxilində metaxarakterlə başlayan boşluq simvollarından və şərhlərdən istifadə etməyə icazə verir #
. Uyğunlaşdıran hər ikisini nəzərə almayacaqdır. Məsələn, java RegexDemo ".at(?x)#match hat, cat, and so on" matter
simvol ardıcıllığı üçün mat
nümunə uyğun gəlir .at
. Varsayılan olaraq, boşluq simvollarına və şərhlərə icazə verilmir və uyğunlaşdırıcı onları axtarışda iştirak edən simvollar kimi qəbul edir.
(?s)
: Nöqtə metaxarakterinin hər hansı digər simvoldan əlavə xətt ayırıcılarına uyğun gəldiyi nöqtə rejimini aktivləşdirir. Məsələn, komanda java RegexDemo (?s). \n
yeni sətir simvolu tapacaq. Defolt dotall-ın əksidir: heç bir xətt ayırıcı tapılmayacaq. Məsələn, komanda Java RegexDemo . \n
yeni sətir simvolu tapmayacaq.
(?m)
^
: Hər bir sətrin əvvəlinə və $
sonuna uyğun gələn çoxsətir rejimini aktivləşdirir . Məsələn, java RegexDemo "(?m)^abc$" abc\nabc
giriş mətnində hər iki ardıcıllığı tapır abc
. Varsayılan olaraq, tək sətirli rejim istifadə olunur: ^
bütün daxil edilmiş mətnin əvvəlinə və $
sonuna uyğun gəlir. Məsələn, java RegexDemo "^abc$" abc\nabc
uyğunluqların olmadığı cavabını qaytarır.
(?u)
: Unicode həssas hərflərin düzülməsini aktivləşdirir. Bu bayraq, ilə birlikdə istifadə edildikdə (?i)
, Unicode standartına uyğun olaraq hərflərə həssas olmayan nümunə uyğunlaşmasına imkan verir. Defolt parametr yalnız hərflərə həssas və US-ASCII simvollarını axtarmaqdır.
(?d)
: Unix tipli sətir rejimini aktivləşdirir, burada uyğunlaşdırıcı kontekstdə meta simvolları .
və yalnız sətir ayırıcısını tanıyır . Standart qeyri-Unix üslublu sətir rejimidir: uyğunlaşdırıcı yuxarıdakı metasimvollar kontekstində bütün sətir ayırıcılarını tanıyır.^
$
\n
İç-içə bayraq ifadələri tutulan qruplara bənzəyir, çünki onların simvolları mötərizə metasimvolları ilə əhatə olunub. Tutulmuş qruplardan fərqli olaraq, iç içə bayraq ifadələri mətn simvollarını tutmayan müntəzəm ifadə konstruksiyası olan qeyri-ələ keçirilən qruplara nümunədir. Onlar mötərizələrin meta simvolları ilə əhatə olunmuş simvol ardıcıllığı kimi müəyyən edilir.
Çoxlu İçəri İçəri Bayraq İfadələrinin Dəqiqləşdirilməsi |
(?m)(?i)) Normal ifadədə çoxlu iç-içə bayraq ifadələrini ya onları yan-yana qoymaqla ( ) və ya onları müəyyən edən hərfləri ardıcıllıqla ( ) yerləşdirməklə müəyyən etmək mümkündür (?mi) . |
Nəticə
Yəqin ki, indiyə qədər dərk etdiyiniz kimi, müntəzəm ifadələr son dərəcə faydalıdır və onların sintaksisinin nüanslarını mənimsədikcə daha da faydalı olur. İndiyə qədər sizi müntəzəm ifadələrin əsasları və
Pattern
.
Pattern
2-ci hissədə biz Regex API-yə daha dərindən baxacağıq və ,
Matcher
və metodlarını araşdıracağıq
PatternSyntaxException
. Mən sizə proqramlarınızda dərhal istifadə edə biləcəyiniz Regex API-nin iki praktik tətbiqini də göstərəcəyəm.
Java-da müntəzəm ifadələr, 3-cü hissə Java-da müntəzəm ifadələr, 4-cü hissə Java-da müntəzəm ifadələr, 5-ci hissə
Başqa nə oxumaq lazımdır: |
|
GO TO FULL VERSION