PHP'de normal ifadelerin nasıl çalıştığına dair örnekler. php'de normal ifadeler

  • 02.08.2019

Normal ifadenin ne olduğuyla başlayalım. İşte sorumun cevabı, "test" kelimesinde "e" harfi var mı? "Orada!" diyorsun. O zaman ikinci soruyu soruyorum, "test" kelimesindeki "e" harfini nasıl buldunuz? Cevap açık, ilk karakteri yani "t"yi alıp aradığımız şeyle yani "e" ile karşılaştırıyoruz. Eşit değillerse, ikinci karakteri yani "e"yi alırız, aradığımız şeyle, yani "e" ile karşılaştırırız. işte! Bir eşleşme bulundu. Cevap: "Test" kelimesi "e" harfini içerir..

Şimdi bana bir soru daha cevaplayın, bu örnekte normal ifade nerede? Umarım buradaki normal ifadenin "test" kelimesinde aradığımız şey olduğunu tahmin etmişsinizdir. Yani bu örnekteki "e" harfi bir düzenli ifadedir.

PHP'de düzenli ifadeler ne için kullanılır? Uygulamamda, örneğin bir e-posta adresinin iyi biçimlendirilmiş olup olmadığını belirlemek için düzenli ifadeler kullanıldı. Bu tür ifadeler, kullanıcı adı ve şifrenin doğruluğunu belirlemek için de kullanılır. Normal ifadeler kullanarak bağlantıdaki adresi bulabilir ve kaydedebilirsiniz. Yapabileceğiniz birçok şey Bunu analiz ederek, normal ifadelerin ana işlevini ve iki yan işlevini tanımlayabilirsiniz. Ana işlev, bu bir dizgedeki eşleşmelerin aranmasıdır. Yan etkiler, bulunan eşleşmeleri kaydediyor ve değiştiriyor.

İlk normal ifade

Teoride, "test" kelimesindeki "e" sembolünü nasıl bulacağımızı anlıyoruz, bu pratikte nasıl uygulanıyor? PHP'de normal ifadeleri kullanmak için genellikle aşağıdaki işlevler kullanılır:

preg_match ("normal ifade (kalıp)", "aramanın yapıldığı değişken", "arama sonucunun kaydedildiği değişken (isteğe bağlı parametre)"); - Eşleştirme işlevi
preg_replace ("normal ifade (kalıp)", "Bulunan eşleşme neyle değiştirilecek", "değişkenle değiştirilecek"); - Değiştirme işlevi

Bu işlevleri kullanmaya başlayalım.. İşte "test" kelimesindeki "e" karakterini bulma örneği:

$a = "deneme";
if (preg_match ("/ e /", $ a)) echo "bulundu !!";

Kod, durumu açıklar, desen tarafından $ a değişkeninde bir şey bulunursa, "bulundu !!" mesajını görüntüleyin. Görüldüğü gibi kalıbımız iki "/" arasındadır. Bu durumda, "/" şablonumuzun başlangıcını ve sonunu sembolize eder... Umarım açık olmuştur.

Bütün bunlar elbette ilginç ... ama bu sadece bizim şablonumuz, ki çok basit, değil mi? Sonuçta, bir değişkende nadiren bir sembol bulmamız gerekir. Çoğu durumda, birçok sembol bulmamız gerekir, ayrıca bilinmeyenler. Nasıl olunur? Kendimize bir sorun belirleyelim ve onu çözmeye çalışalım. Sayılardan ve bilinmeyen bir İngilizce harften oluşan bir dizimiz olduğunu varsayalım.

Bu mektubu nasıl buldunuz? İngiliz alfabesinin herhangi bir harfi olabilir, nasıl tanımlayabilirsiniz? Kendi sorunuzu kendiniz yanıtladınız, herhangi bir harf var, yani a'dan z'ye kadar. Aralıklar normal ifadelerde kullanılabilir. Hangi karakteri aradığımızı bilmiyorsak, ancak bu karakterin İngiliz alfabesinin bir harfi olduğunu kesin olarak biliyorsak, kayıt aşağıdaki gibi olacaktır:

$a = "123a321";
if (preg_match ("//", $ a)) echo "bulundu !!";

Aralığın "[" "]" parantezleri içine alındığını unutmayın. Bu parantez içine alınan her şey şu şekilde tanımlanır: bir karakter, bu durumda karakter a'dan z'ye değişir. Bir harf değil, bir sayı bulmamız gerekirse, kayıt şöyle olacaktır:

$a = "abc1cba";
if (preg_match ("//", $ a)) echo "bulundu !!";

Ayrıca normal ifadelerin büyük/küçük harf duyarlı olduğunu da belirtmek isterim, bu nedenle "A" ve "a" karakterleri tamamen farklıdır, bunları ve bu karakterleri aramak için şöyle yazarlar:

$a = "123a321";
if (preg_match ("//", $ a)) echo "bulundu !!";

Rusça harfler için de bir arama var, İngilizce ile aynı şekilde gerçekleştirilir:

$a = "123ы321";
if (preg_match ("/ [a-za-z] /", $ a)) echo "bulundu!!";

meta karakterler

Bir dizide bilinmeyen bir karakteri nasıl arayacağımızı öğrendik. Ya birkaç sembol bulmamız gerekirse? Sözde metakarakterler kurtarmaya geliyor ... Rakamlar, harfler içeren bir dizimiz olduğunu varsayalım, onu şablonda nasıl açıklayalım? Bunu yapabilirsiniz:

dize - 123а321
örneklem -

Hmm ... şablon dizimizle gerçekten eşleşiyor ve uygunluk açısından kontrol edildiğinde, uzun zamandır beklenen gerçeği verecek! Ama bir tür hantal kayıt, sence de öyle değil mi?

Bunu nasıl kısaltabileceğiniz aşağıda açıklanmıştır:

dize - 123а321
örneklem - *

Bana çok daha kısa geliyor "*" sembolü nedir? Bu tam meta karakterdir, tanımladığımız karakterin (yani, 0'dan 9'a kadar sayıları veya a'dan z'ye İngiliz alfabesinin harflerini içerebilen bir karakter) süresiz olarak veya bir kereden fazla tekrarlanabileceği anlamına gelir. Evet evet! Bu metakarakter boş bir değişkende eşleşecek, çünkü tanımladığımız sembolün yokluğu bile true dönecek! Hatırla bunu

Başka hangi meta karakterler var?

Örneğin "+" meta karakteri Küçük bir istisna dışında "*" meta karakterine neredeyse benzer. "*", karakter olmasa bile true değerini döndürür ve "+", en az bir karakterin varlığını kontrol eder. Diğer bir deyişle, dize varlığı gerektiriyorsa asgari tek karakter sonra "*" yerine "+" kullanın

Meta karakter "?" Bu, dizenin birden fazla gerekli karakter içermemesi gerektiği anlamına gelir. Anlattığım son iki metakarakter için birkaç örnek vereyim.

Kullanıcının şifresinin doğruluğunu kontrol etmemiz gerektiğini varsayalım. Kullanıcının şifresinin ne içermesi gerektiğini düşünelim mi? Öncelikle, en az bir karakter olmalı. İkinci olarak, yalnızca İngiliz alfabesinin sayılarını ve harflerini içermelidir, bu nedenle normal ifade şöyle görünecektir:

$a = "qwerty12345";

Hangi karakterlere izin verdik? Herhangi bir kayıt ve sayının İngilizce harfleri. Şimdi şifre yerine boş bir satır bırakmayı deneyin.

$a = "";
if (preg_match ("/ + /", $ a)) echo "Parola doğru";

"Şifre doğru" mesajını görmeyeceksiniz. Niye ya? Çünkü "+" meta karakteri, dizeyi en az bir karakterin varlığı için kontrol etti.

Ve şimdi küçük bir hile, ifademize bir bakalım, diyelim ki içinde boşluk bırakmadık, değil mi? şifrenin sonuna bir boşluk koyun ve çalıştırın

$a = "qwerty12345";
if (preg_match ("/ + /", $ a)) echo "Parola doğru";

Ve neden doğru şifre ile ilgili mesajımızı görüyoruz? Oldukça basit ... function preg_match(); ilk maçta kontrolünü durdurur. Yani "q" karakteri bizim tanımladığımız örüntüyle eşleşiyor ve diğer her şey fonksiyon için artık önemli değil, peki ne yapmalı? Bunu nasıl düzelteceğiniz aşağıda açıklanmıştır:

$a = "qwerty12345";
if (preg_match ("/ ^ + $ /", $ a)) echo "Parola doğru";

İfadenin başına "^" ve sonuna "$" ekleyerek fonksiyona kalıpla eşleşmesini söylüyoruz. herşey hat. Bu kodu çalıştırırsanız, mesajı görmezsiniz, çünkü şifrenin sonunda geçersiz bir karakter bulunur - boşluk

Şimdi "+" meta karakterini "?" olarak değiştirin. Sizce ne olacak? Şifre birden fazla karakter içerdiğinden, şifrenin doğruluğu ile ilgili doğru mesaj bulunmayacaktır. Umarım bu yaygın olarak kullanılan üç meta karakterin nasıl çalıştığını doğru bir şekilde anlatabilmişimdir.

Bazen "hayır" daha iyidir

En azından şifrenin doğruluğunu nasıl kontrol edeceğimizi öğrendik ve bu iyi! Size bir dizide bir şey bulmanın başka bir yolunu anlatayım. Diyelim ki bir dizgede sayıların yokluğunu kontrol etmemiz gerekiyor. Nasıl yapılır? İşte satır:

(Hayat bal gibi görünmesin diye bu "-_ + ()" sembollerini kasten içine soktum...) Aşağıdaki ifadeyi oluşturabiliriz:

Ancak kabul etmelisiniz, çünkü bir dizede hangi karakterlerin kullanıldığını her zaman bilmiyoruz, ancak içinde sayı olmaması gerektiğini kesin olarak biliyoruz! Bu nedenle, satırları atlayacak bir şablon yazmak daha mantıklı olacaktır. Numara rakamlar ve içinde olanlar değil "Aman Tanrım, ne kadar anlaşılmaz semboller !!!"... İşte bu tür görevler için iyi biçimlendirilmiş bir ifade örneği:

$a = "a -_ + ()";
if (preg_match ("/ ^ [^ 0-9] + $ /", $ a)) echo "Sayı yok!";

Bunu nasıl başardık? Bir sembol tanıttık ancak! Başa yerleştirilen "^" ([^ 0-9]) başlığı, bu karakterin satırının içerdiği anlamına gelir. yapmamalı umarım anlamışızdır

Pekala, biraz toparlayalım ... Açıklamalı iki örnek vereceğim, bu sırada arama sonucunu bir değişkene nasıl kaydedeceğimizi ve posta adresinin doğruluğunu nasıl kontrol edeceğimizi öğreneceğiz.

Gördüm, kurtardım!

Bloğum

$a = " Bloğum";
preg_match ("/ / ", $a);

Normal ifademizde, bağlantıya dahil edilebilecek tüm olası karakterleri açıkladık. Ayrıca ifademizdeki tırnak ve "/" karakterlerine de dikkat çekmek istiyorum.. Başlarında ters eğik çizgi var, ne için? Mesele şu ki, "/" ve tırnak işareti kendi başlarına özel karakterlerdir. Ve şablonun onları sıradan semboller olarak algılaması için onları taramamız gerekiyor. Özel karakterlerden önce ters eğik çizgi eklenerek tarama yapılır. umarım açıktır

$a = " Bloğum";
preg_match ("/ / ", $a, $b);

Ve buna göre, bulunan bağlantının saklanacağı $ b değişkeni şeklinde ek bir parametre eklemeniz gerekir. Ayrıca arama sonucunun bir diziye yerleştirildiğini de bilmeniz gerekir. Yani $ b değişkeni bir dizidir. Aradığımız bilgi dizin 1'in altındadır. Bu, arama sonucunun $ b değişkeninde olduğu anlamına gelir. sonucu ekranda göstereceğiz:

$a = " Bloğum";
preg_match ("/ / ", $a, $b);
yankı $b;

Doğru adres başarının anahtarıdır!

Peki, bir sonraki adıma, sorunun cevabı e-posta doğru mu? İlk olarak, adreslerde hangi karakterlere izin verildiğini bilmeniz gerekir. Bildiğim kadarıyla izin verilen karakterler şunları içerir:

  • İngilizce harfler, sayılar, "_", "-" emmmm gibi her şey... Bundan devam edelim.
  • Sırada "@" var
  • sonra ingilizce harfler
  • Ayrıca, nokta
  • Ve yine, İngilizce harfler ...

Yani normal ifade aşağıdaki gibi olacaktır:

$a = " [e-posta korumalı]";
if (preg_match ("/ ^ [e-posta korumalı]+. + $ / ", $ a)) echo" E-posta adresi doğru! ";
else echo "E-posta adresi doğru DEĞİLDİR!";

Şey ... Umarım bu tür kayıtlar şimdi sizi korkutmaz ve onları oldukça anlayabilirsiniz.

Devamında bir şey söylemek istiyorum. Makalenin hantal olduğu ortaya çıktı ve aynı zamanda olasılıkların sadece bir kısmını kapsıyordu. Bu cümleyi okuyorsanız, büyük olasılıkla sonuna kadar okudunuz, bu yüzden çok teşekkür ederim.

Bir cms blogunun geliştirilmesine ilişkin makale döngüsüne gelince, döngünün ilk kısmı Kapatıldığını ilan ediyorum! Yakın gelecekte yönetici panelini uygulamaya başlayacağız, bu yüzden "geçmeyin" Herhangi bir sorunuz varsa, memnuniyetle yanıtlarım. Senin için en iyisi, her şeye sahibim!


PHP dilinin en güçlü ve kullanışlı özelliklerinden biri düzenli ifadeleri desteklemesidir. Hem yeni başlayanlar hem de oldukça deneyimli birçok programcı, düzenli ifade dilinin dış karmaşıklığı ve karmaşasından korkar. Ama sizi temin ederim - buna değer. Normal ifadelerin kullanılması, metin ve kötü yapılandırılmış verilerin işlenmesini büyük ölçüde kolaylaştırır.


Normal ifadeler, özel bir dilde yazılmış ifadelerdir. Paniğe kapılmayın, dili anlamak için yeterince basit, sadece deneyim ve pratik gerekiyor.


Metniniz olduğunda (örneğin, Microsoft Word'de) tekrar tekrar durumlarla karşılaştığınızı ve içinde önemli bir şey bulmanız gerektiğini düşünüyorum. Tam olarak ne aradığınızı biliyorsanız, her şey basittir: arama iletişim kutusunu açtılar, istenen kelimeyi girdiler, düğmeye bastılar ve işte - metin bulundu.


Ancak, yalnızca aradığınız bilgi türünü önceden biliyorsanız ne yaparsınız? Örneğin, göreviniz birkaç yüz sayfa belgedeki tüm e-posta adreslerini bulmaktır. Bazıları belgeye manuel olarak göz atacak, bazıları bir köpek (@) arayacak ve onu arayacaktır. Katılıyorum - her iki değişken de ağır emek, nankör emek.

Normal ifadelerin kurtarmaya geldiği yer burasıdır. Bazı yaklaşımlarda, düzenli ifadeler, metin üzerine bindirilen maskeler veya kalıplarla karşılaştırılabilir: metin maskeyle eşleşiyorsa, bu istenen parçadır. Ancak düzenli ifadelerin kullanımına bakmadan önce sözdizimlerine bir göz atacağız.

Normal ifade, belirli yasalara ve kurallara göre oluşturulmuş bir metin dizesidir. Bir dize, karakterlerden ve karakter gruplarından, meta karakterlerden, niceleyicilerden ve değiştiricilerden oluşur.

Bu durumda, semboller, herhangi bir alfabenin herhangi bir sembolü olarak anlaşılır. Ve sadece okunabilir olanlar değil. Bir ifadeye kolayca okunamayan bir karakter ekleyebilirsiniz, bunun için kodunu onaltılık biçimde bilmeniz yeterlidir. Örneğin:

// okunabilir karakterler a Е // okunamayan karakterler ve kodlar \ x41 - "A" harfiyle aynı \ x09 - tablolama karakteri

Bir karakter grubu, sırayla yazılmış bir dizi karakterdir:

Ort. ACZms

Hemen dikkatinizi çekiyorum - normal ifadelerdeki "boşluk" da önemli bir karakter olarak kabul edilir, bu nedenle ifade yazarken dikkatli olun. Örneğin, bu grappa karakterleri FARKLI ifadelerdir:

ABVGDE ABC NEREDE

Bir sonraki dil öğesi meta karakterlerdir. "Meta" öneki, bu sembollerin diğer bazı sembolleri veya onların gruplarını tanımladığı anlamına gelir. Tablo, normal ifade dilinin ana meta karakterlerini gösterir:

Özel Karakterleri Belirtmek İçin Meta Karakterler
() Parantez. İç içe ifadeleri tanımlayın.
| Seçim meta karakteri
^ Satır meta karakterinin başlangıcı
$ Satır sonu meta karakteri
\ n Satır besleme karakteri (onaltılı 0x0A)
\ r Satır başı (hex 0x0D)
\ T Sekme karakteri (onaltılı 0x09)
\ xhh 0xhh onaltılık kodlu karakter ekle, örneğin \ x42 Latince "B" harfini ekleyecektir
Karakter Gruplarını Belirtmek için Meta Karakterler
. Puan. Herhangi bir karakter.
\ NS Basamak (0-9)
\ NS Rakam değil (0-9 arasındaki karakterler dışında herhangi bir karakter)
\ s Boş karakter (genellikle boşluk ve sekme karakteri)
\ S Boş olmayan karakter (\ s meta karakteri tarafından tanımlanan karakterler dışında her şey)
\ w Bir "sözlük" karakteri (kelimelerde kullanılan bir karakter. Genellikle tüm harfler, tüm sayılar ve bir alt çizgi ("_"))
\ B \ w meta karakteri tarafından belirtilen karakterler dışındaki her şey

Tablonun ikinci yarısındaki meta karakterlerin hatırlanması çok kolaydır. "d" rakam (rakam), "s" sembol (sembol), "w" kelimedir (kelime). Harf büyükse, grup açıklamasına "DEĞİL" eklemeniz gerekir.

Örneğin, "Kırmızı mayo 1812 numaralı, yeşil mayo 2009" metnini alalım. En basit düzenli ifadelerin örneklerine bakalım:

\ d \ d \ d \ d - 1812 ve 2009'u bulur \ D - tüm harfleri, boşlukları ve noktalama işaretlerini bulur \ s - metindeki tüm boşlukları bulur.

Ama sonuçta, örneğimizdeki yıl dört ile değil iki sayı ile yazılabilir, kelimelerin başka çekimleri olabilir, vb. Köşeli parantezler kullanılarak belirtilen karakter alt kümeleri burada yardımcı olabilir:

Herhangi bir rakam anlamına gelir (\ d ile aynı) - çift rakam anlamına gelir - Latin alfabesinin herhangi bir karakterini (her durumda) veya rakamı belirtir.

Örneğin, test satırındaki \ d \ d \ d ifadesi yalnızca 1812'yi bulur, 2009'u bulamaz. Bu ifade "son basamağı 0,2,4,6 olan tüm dört basamaklı dizileri bul veya 8".

Sadece niceleyicilerden ve değiştiricilerden bahsetmemiz gerekiyor.

niceleyici bir karakterin veya karakter grubunun kaç kez görüneceğini belirleyen özel bir yapıdır. Niceleyici, küme parantezleri "()" içine alınır. İki kayıt formatı vardır: kesin ve aralık. Kesin biçimi şöyle yazılır:

Burada X, bir önceki karakterin veya grubun tekrarlanması gereken sayıdır. Örneğin, ifade

İkinci gösterim şekli aralıktır. olarak yazılmıştır

(X, Y) // veya (, Y) // veya (X,)

burada X minimum ve Y maksimum tekrar sayısıdır. Örneğin:

"iki ila dört ardışık basamak" olarak okur. Sınırlardan biri belirtilmemişse, herhangi bir sınırlama ima edilmez. Örneğin:

\ w (3,) - üç veya daha fazla harf. \ d (, 5) - hiç rakam yok veya rakam var, ancak beşten fazla değil.

Niceleyiciler tek bir karaktere veya bir gruba uygulanabilir:

[A-Ya-ben] (1,3)

Bu yapı, metinden bir, iki veya üç harfli tüm Rusça kelimeleri seçecektir (örneğin, "veya", "değil", "Ben", "Gidiyorum" vb.)

Küme parantezleri c'ye ek olarak, üç meta karakter niceleyici daha vardır: "*" (yıldız), "+" (artı) ve "?" (soru). Minimum ve maksimum tekrar sayısının önceden bilinmediği durumlarda kullanılırlar. Örneğin, e-posta adreslerini ararken, bir kullanıcı adında ("köpek" öncesi) ve alan adında ("köpek"ten sonra) kaç karakter olacağını önceden bilemezsiniz.

"*" meta karakteri "sıfırdan veya daha fazla herhangi bir sayı" olarak okunur, yani. tasarım

tam yokluğu da dahil olmak üzere herhangi bir sayıda ardışık harfi tanımlar.

"+" simgesi yıldızdan yalnızca en az bir simge gerektirmesi bakımından farklıdır. Onlar. tasarım

bir veya daha fazla rakamın olduğu herhangi bir sayısal diziyle eşleşir.

Sembol "?" tek bir karakterin yokluğu veya varlığıyla eşleşir. Onlar. tasarım

bir veya iki basamak olan herhangi bir sayısal diziyle eşleşir.

Burada "*" ve "+" antifierlerinin böyle bir özelliğinden bahsetmeye değer. açgözlülük... Sonuç olarak, varsayılan olarak bu karakterlerin olası en uzun karakter dizisiyle eşleşmesidir. Örneğin, "Anne çerçeveyi yıkadı" satırı için ifade:

"mama soap ra"yı seçecek, ki bu biraz beklenmedik bir durum çünkü bizim "ma" almamız gerekiyordu. Bu davranışı değiştirmek için "?" (soru işareti), niceleyiciden hemen sonra yazılır. Niceleyicilerin iştahını, onları en uzun eşleşmeyi değil, ilk eşleşmeyi döndürmeye zorlayarak bastırır. Şimdi önceki örneği değiştirelim:

ve gerekli "ma" eşleşmesini alıyoruz.

Dilin son unsuru değiştiriciler... Değiştirici, düzenli ifade analizinin "sistem" parametrelerini tanımlayan özel bir karakterdir. Bu tür sadece dört sembol vardır, hem ayrı ayrı hem de aynı anda kullanılabilirler:

ben Büyük/küçük harfe duyarsız modu açar, ör. büyük ve küçük harfler ifadede farklılık göstermez.
m Aranan metnin birden çok satır olarak ele alınması gerektiğini belirtir. Varsayılan olarak, normal ifade motoru, gerçekte ne olduğuna bakılmaksızın metni tek bir dize olarak ele alır. Buna göre, "^" ve "$" meta karakterleri tüm metnin başlangıcını ve sonunu belirtir. Bu değiştirici belirtilirse, sırasıyla metnin her satırının başına ve sonuna işaret ederler.
s Varsayılan meta karakter "." tanımında bir satır besleme karakteri içermez. Onlar. çok satırlı metin için, /.+/ ifadesi beklendiği gibi metnin tamamını değil, yalnızca ilk satırı döndürür. Bu değiştiricinin belirtilmesi bu sınırlamayı kaldırır.
sen Varsayılan olarak tüm meta karakterleri açgözlü yapmaz. Dilin bazı modifikasyonlarında (özellikle PHP'de), "U" yerine, anlama daha uygun olan "g" karakteri kullanılır ("g", İngilizce "açgözlü", "açgözlü" için bir kısaltmadır. ).

Tablo, düzenli ifadelerin en popüler ve kullanışlı örneklerini göstermektedir. Bazıları size karmaşık ve hantal gelebilir, ancak ayrıntılı bir çalışma ile şüphesiz çözeceksiniz.

PHP'de düzenli ifadeler.

PHP'de düzenli ifadelerle çalışmak için özel işlevler vardır, bunların listesi ve kısa bir açıklaması tabloda verilmiştir:

int preg_match (dize deseni, dize konusu [, dizi eşleşmeleri])

İşlev, konunun içeriğinin kalıpla eşleşip eşleşmediğini kontrol eder. Eşleşme bulunursa 1 döndürür, aksi takdirde 0 döndürür. İsteğe bağlı bir dizi parametresi, eşleşmeler belirtirseniz, işlev yürütüldüğünde buna tek bir öğe eklenir - bulunan ilk eşleşme.

"; print_r ($ bulundu);?>

int preg_match_all (dize modeli, dize konusu, dizi eşleşmeleri [, int sırası])
İşlev öncekiyle aynıdır, tek farkla - tüm metni arar ve eşleşmeler dizisinde bulunan TÜM eşleşmeleri döndürür.
karışık preg_replace (karma model, karışık değiştirme, karışık konu [, int limit])
Önceki her iki işlev gibi, preg_replace de bir kalıpla eşleşen bir metin parçasını arar. İşlev, bulunan tüm parçaları parametrelerde belirtilen metinle değiştirir.Temizlemeden önce:\ n $ metin \ n \ n "; $ metin = preg_replace (" / (\ n \ s (2,)) / "," ", $ metin); yankı" Temizlikten sonra:\ n $ text "; // metni özel karakterlerden arındırılmış olarak gösterecek // ve fazladan boşluklar mı?>
karışık preg_replace_callback (karma desen, karışık geri arama, karışık konu [, int limit])
İşlev, öncekinin genişletilmiş bir sürümüdür. Temel fark, metni ayrıştıracak ve alternatif metni oluşturacak işlevin adının parametrelerde bu işleve iletilmesidir.
dizi preg_split (dize deseni, dize konusu [, int limit [, int bayrakları]])
Bu işlev patlat () ve bölme () işlevlerine benzer. Özelliği, ayırıcının sabit bir dize değil, düzenli bir ifade olmasıdır. İşlev, orijinal verileri öğelere böler ve bunları çıktı dizisine yerleştirir.
dizi preg_grep (dize modeli, dizi girişi)
İşlev, dizilerde düzenli arama yapmak için tasarlanmıştır. Arama için bir şablon ve bir dizi girdi verisi belirtilir ve yalnızca şablonla eşleşen öğelerden oluşan bir dizi döndürülür.

Yukarıdaki işlevler listesi tam olmaktan uzaktır, ancak düzenli ifadelerle çalışmaya başarılı bir şekilde başlamak için oldukça yeterlidir. Bu konuyla ilgileniyorsanız, ek literatürü okuduğunuzdan emin olun (örneğin, Friedl'in "Normal İfadeler" kitabı). Ek olarak, eğitim amacıyla, düzenli ifadeleri test etmek için özel programlardan birini (örneğin, "PCRE" veya "RegEx Builder") yüklemenizi öneririm.

Perl'de düzenli ifadelerin en yaygın kullanımı, arama ve değiştirme operatörleridir. s //, m /, paketin operatörleri =~ veya != vesaire. Kural olarak, bu operatörlerin tümü aşağıdakiler gibi benzer seçeneklere sahiptir:

Bu seçeneklere genellikle "/ x" adı verilir. Yeni yapıyı kullanarak şablonların içinde bile kullanılabilirler (? ...)

Normal ifadeler veya kalıplar, Unix normal ifade prosedürleriyle aynıdır. İfadeler ve sözdizimi Henry Spencer'ın V8 Ücretsiz Rutinlerinden ödünç alınmıştır ve burada ayrıntılı olarak verilmiştir.

Şablonlar, genellikle egrep standardı olarak adlandırılan aşağıdaki meta karakterleri (diğer karakter gruplarını temsil eden karakterler) kullanır:

Meta karakterlerin değiştiricileri vardır (meta karakterden sonra yazılır):

Diğer tüm durumlarda, küme parantezleri normal (normal) karakterler olarak kabul edilir. Bu nedenle, "*" (0,), "+" - (1,) ve "?" ile eşdeğerdir. - (0,1). n ve m 65536'dan büyük olamaz.

Varsayılan olarak, meta karakterler açgözlüdür. Eşleşme, aşağıdaki meta karakterlerin etkisi göz ardı edilerek mümkün olduğunca çok yayılır. "İştahlarını azaltmak" istiyorsanız "?" Sembolünü kullanın. Bu, meta karakterlerin anlamını değiştirmez, sadece yayılmayı azaltır. Böylece:

Desenler çift tırnak ile aynı şekilde çalışır, böylece içlerinde `\` - karakterleri (ters eğik çizgi karakterleri) kullanabilirsiniz:

\ T - sekme karakteri
\ n - Yeni hat
\ r - taşıma dönüşü
\a - biçim çevirisi
\ v - dikey sekme
\ a - Arama
\ e - kaçmak
\033 - bir karakterin sekizli gösterimi
\ x1A - onaltılık
\ C [ - kontrol karakteri
\ l - sonraki karakterin küçük harfi
\ sen - büyük harf -//-
\ L - \ E'ye kadar tüm küçük harfler
\ U - zirvede - // -
\ E - kayıt değişiklik sınırlayıcı
\ Q - bir eylemi meta karakter olarak iptal etme

Ek olarak, Perl'e aşağıdaki meta karakterler eklendi:

Bunların hepsinin "bir" karakter olduğunu unutmayın. Sıralamayı belirtmek için değiştiricileri kullanın. Yani:

Ayrıca hayali meta karakterler de var. Değerin değiştiği noktada var olmayan karakterlerin atanması. Gibi:

Bir kelime sınırı (\ b), \ w ve \ W karakterleri arasındaki hayali noktadır. Bir karakter sınıfı içinde, "\ b" bir geri al karakterini belirtir. meta karakterler \ A ve \ Z- "^" ve "$" ile benzer, ancak "^" satırının başı ve "$" satırının sonu çok satırlı bir satırdaki her satır için geçerliyse, o zaman \ A ve \ Zçok satırlı bir dizenin tamamının başlangıcını ve sonunu belirtir.

Kalıp içinde gruplama (parantez) kullanılıyorsa, grup alt dizi numarası "\ digit" olarak gösterilir. Bir ifade veya blok içindeki bir kalıbın arkasında, bu gruplara "$ rakamı" olarak atıfta bulunulduğunu unutmayın. Ek olarak, ek değişkenler vardır:

Örnek:

$ s = "Bir 1 İki 2 ve Üç 3"; if ($ s = ~ / (\ d +) \ D + (\ d +) /) ("$ 1 \ n" yazdır; # Sonuç "1" yazdır "$ 2 \ n"; # "2" yazdır " $ + \ n" ; # "2" yazdır "$ & \ n"; # "1 iki 2" yazdır "$` \ n "; #" Bir "yazdır" $ "\ n"; # "ve üç 3" )

Perl sürüm 5, ek şablon yapıları içerir:

Örnek:

$s = "1 + 2-3 * 4"; if ($ s = ~ / (\ d) (? = -) /) # "-" işaretinin arkasındaki rakamı bulun ("$ 1 \ n" yazdırın; # Sonuç "2") else ("arama hatası \ n" yazdırın) ;)

(?! desen) - olumsuzlama ile ileriye bakmak:

Örnek:

$s = "1 + 2-3 * 4"; if ($ s = ~ / (\ d) (?! \ +) /) # Ardından "+" gelmeyen bir rakam bulun ("$ 1 \ n" yazdır; # Sonuç "2") else (yazdır " arama hatası \ n ";)

(? ismx) - "dahili" değiştiriciler. Örneğin, şablonun içinde bir değiştirici belirtmeniz gereken şablonlarda kullanmak uygundur.

Normal ifade kuralları. (normal ifade)

  1. Bir meta karakter olmadığı sürece herhangi bir karakter kendini gösterir. Bir meta karakteri geri almanız gerekiyorsa, önüne "\" koyun.
  2. Bir karakter dizisi, bu karakterlerin bir dizisini belirtir.
  3. Olası karakterler (sınıf) kümesi köşeli parantez "" içine alınmıştır; bu, parantez içinde belirtilen karakterlerden birinin bu yerde görünebileceği anlamına gelir. Parantez içindeki ilk karakter "^" ise - belirtilen karakterlerden hiçbiri ifadede bu yerde görünemez. Bir sınıf içinde, bir dizi karakteri belirtmek için "-" karakterini kullanabilirsiniz. Örneğin, a-z Latin alfabesinin küçük harflerinden biridir, 0-9 bir sayıdır vb.
  4. PHP portalı forumu. SU

) Size bir sayfanın kaynak kodunun belirli parçalarını bulmak için normal ifadeler kullanmanın bir örneğini gösterdim. Şimdi onları kendimiz yazmayı öğreneceğiz. Bu beceri, yazmanıza, gereksiz parçalardan metni temizlemenize, büyük hacimli metinlerde gerekli parçaları aramanıza vb. yardımcı olacaktır.

Bu konu oldukça zor, ancak en önemli noktaları kısaca vurgulamaya çalışacağım. Ne kadar yapabilirim bilmiyorum ama umarım ders faydalı olur.
Bu nedenle, başlangıç ​​olarak, PHP'de normal ifadelerle çalışmak için birkaç işlev vardır, ancak en sık üçü kullanılır:

  • preg_replace - normal ifadeyle eşleşen metni arayın ve değiştirin;
  • preg_match - sadece normal arama;
  • preg_split - metni arayın ve bölün.

En azından önceki derslerde bunları kullandık. Bunun yerine, preg_match yerine preg_match_all vardı, ancak bu temelde aynı şeydir, yalnızca ikincisi, ilk bulgudan sonra aramayı kesmez. Yani, preg_match kullanırsak, tüm oluşumları değil, yalnızca ilkini bulacağız.

Hangi durumda hangi işlevin kullanılacağı seçimi oldukça basittir. Değiştirmemiz gerekiyor - sayfa kodunun gereksiz kısımlarını kaldırmamız gerektiğinde olduğu gibi değiştirme kullanıyoruz, hatırladın mı?

$ sayfa = preg_replace ("/ ^] / i "," ", $ sayfa); $ sayfa = preg_replace (" / ^] / i "," ", $ sayfa); $ sayfa = str_replace (""," ", $ sayfa);

Fonksiyonun ilk parametresi, ne aradığımızı belirleyen bir normal ifadedir. İkincisi, değiştirdiğimiz şey. Üçüncü - Baktığımız yer. Bu nedenle, burada $ page değişkenini aldık ve preg_replace işlevinin sonucunu ona atadık, burada tüm input type = onay kutularını, ayrıca açılış ve kapanış etiketlerini aradık. Onları " ile değiştirdiler, yani basitçe silindiler. Umarım burada her şey açıktır. Biraz sonra ifadenin kendisinin (fonksiyonun ilk parametresi) analizine geçeceğiz.
Ayrıca metnin geri kalanındaki tüm bağlantıları bulmak için kullanışlı olan preg_match_all kullanımına bir örnek vardı. Daha sonra, ayrıştırdığımız anahtar kelimeleri içerdikleri için bağlantılara ihtiyacımız vardı. İşte olanlar:

Preg_match_all ("/ ]+?>(.*?)<\/a>/ uis ", $ sayfa, $ tamam); için ($ j = 0; $ j ".$tamam [$j].""; }

İlk parametre, yine, doğal olarak "a" etiketine dahil edilen tüm bağlantıları bulmak için normaldir (html işaretlemesi ile dost değilseniz, o zaman okuyun). İkincisi, aramanın gerçekleştirileceği metni içeren bir değişkendir. Üçüncü parametre, sonucun yerleştirildiği bir değişkendir - $ tamam. Bundan sonra, ihtiyacımız olan anahtar dosyaları elde etmek için yalnızca gerekli tüm $ ok öğelerini gözden geçirmek kalır. Ayrı olarak, çıktıda çok boyutlu bir dizi aldığımız söylenmelidir. Bu yüzden bu kadar karmaşık bir şekilde çıktı alıyoruz: $ ok [$ j]. Dizinin yapısını görmek için aşağıdaki işlevi kullanın, her şeyi anlayacaksınız.

Print_r ($ tamam);

Burada, iş için kullandığımız işlevleri bulduk gibi görünüyor. Şimdi geriye kalan tek şey, bu yöntemlerin her birinin ilk parametresi olan bu çok düzenli ifadelerin nasıl yazılacağını öğrenmek. Gelelim en önemli şeye.

düzenli nasıl yazılır

İlk olarak, temel yapılara bir göz atalım. İfadelerin seçenekleri vardır. Bir harfle belirtilirler ve sonunda bir eğik çizgi ile yazılırlar.

Ek olarak, aşağıdaki meta karakterler desteklenir:

Meta karakterler de değiştiricilere sahip olabilir:

Pekala, şimdi son dersten müdavimlerimizin analizine geçebiliriz. Yukarıdaki tabletlere dayanarak, elimizde ne olduğunu anlamaya çalışalım. İşte ifade:

/^] / ben

İlk ve son eğik çizgi "/", içlerinde düzenli bir ifade olduğunu gösterir. Aynı zamanda, sonuncudan sonra "i" koyarız, bu ilk tabloda olduğu gibi bir seçenektir - büyük/küçük harfe duyarlı değildir. Eğik çizgilerin içinde, normal çizginin kendisi. Küçüktür işareti ve bir giriş etiketi ile başlar ve ardından, aranması basit bir metin olan nokta işaretine kadar devam eden her şey. Ancak noktanın kendisi ve ondan sonraki semboller - bu zaten daha ilginç. Bu durumda yapı ". *?" herhangi bir karakter dizisi anlamına gelir. Yani, sadece metni ve verilen yapıyı birleştirirseniz, ilk oluşumdan sonuna kadar tüm metni seçeceğiz. Durdurmak için, "büyüktür" kapanış html etiketini veya yeni satır karakterini karşılamanız gerekir. Bu tasarım bize sadece şu fırsatı veriyor:

Köşeli parantez içindeki semboller, mantıksal bir VEYA ile bağlantılıdır. Son, büyüktür işareti VEYA bir satırın başlangıcıdır.
Tüm ifade bu, içinde başlangıç ​​koşulunu, orta ve bitiş koşulunu belirledik. Zor değil, değil mi? İşte netlik için bir örnek:

Her şeyi sağlamlaştırmak için bir tane daha parçalayalım. Bağlantılar için onları aradık:

/]+?>(.*?)<\/a>/ kullanıcı

ifadesini okuduk. Yine, önce eğik çizgileri ve seçenekleri atın. Tanımlamadığım "u" dışında "uis" bayrakları anlaşılabilir - Unicode kodlamasını kullandığımızı gösterir. Pek bir şey kalmadı. Başlangıç, açılan "a" etiketidir, ardından sınıf gelir.

bu, daha fazla veya daha az DEĞİL (html etiketlerini açma ve kapatma), yani bu durumda herhangi bir karakter anlamına gelir. "+?" Sınıfa eklenir, bu da bu sınıfın 1 veya daha fazla kez bulunacağı anlamına gelir (ancak en az 1 kez kesin). Ardından "a" etiketi için kapanış html etiketi gelir. Grup tarafından belirlenen bağlantının içinde metin var

Sonuçta orada ne tür bir metin olacağını bilmiyoruz, bu yüzden böyle bir grup tanımlıyoruz. Ve sonunda, "a" kapanış etiketi:

Düz metin olarak algılanması için eğik çizgiden ters eğik çizgi ile çıktığımızı lütfen unutmayın.

Füh. Konu gerçekten oldukça karmaşık, pratik gerektiriyor. Belki de pek uygun olmayan bir şey yapıyorum ve siz başka, daha doğru düzenli ifadeler oluşturabilirsiniz, ancak ben de sizin gibi kendi kendini yetiştirmiş bir insanım, bu yüzden kesinlikle yargılamayın, bunun yerine seçeneklerinizi yorumlarda paylaşın. Ayrıca, net olmayan bir şey varsa - yorumlar ve bir iletişim sayfası hizmetinizdedir.

Normal ifadeler, metinde bir alt dize bulmak için özel kalıplardır. Onların yardımıyla, şu görevleri bir satırda çözebilirsiniz: "dizenin sayı içerip içermediğini kontrol edin", "metindeki tüm e-posta adreslerini bulun", "birkaç ardışık soru işaretini bir tane ile değiştirin".

Popüler bir programlama bilgeliği ile başlayalım:

Bazı insanlar bir problemle karşılaştıklarında "Evet akıllıyım, normal ifadelerle çözerim" diye düşünürler. Şu an iki problemleri var.

Örnek şablonlar

Birkaç basit örnekle başlayalım. Aşağıdaki resimdeki ilk ifade, ilk harfin "k" olduğu, ikincisinin herhangi bir Rus harfi olduğu ve üçüncünün büyük/küçük harfe duyarlı olmayan bir "t" olduğu (örneğin, "kedi" veya "CAT" bu şablonla eşleşir). İkinci ifade metinde saati 12:34 formatında arar.

Herhangi bir ifade bir sınırlayıcı karakterle başlar. / sembolü genellikle olduğu gibi kullanılır, ancak düzenli kalıplarda özel bir amacı olmayan diğer sembolleri de kullanabilirsiniz, örneğin ~, # veya @. / ifadesi ifadede görünebilirse, alternatif sınırlayıcılar kullanılır. Ardından aradığımız dizenin kalıbı gelir, ardından ikinci bir sınırlayıcı gelir ve sonunda bir veya daha fazla bayrak harfi olabilir. Metin ararken ek seçenekler sunarlar. İşte bazı bayrak örnekleri:

  • i - aramanın büyük/küçük harfe duyarlı olmaması gerektiğini söylüyor (varsayılan olarak büyük/küçük harfe duyarlı)
  • u - aranan ifadenin ve metnin yalnızca Latin harflerini değil, utf-8 kodlamasını kullandığını söylüyor. Onsuz, Rusça (ve Latin olmayan diğer) karakterleri aramak düzgün çalışmayabilir, bu nedenle her zaman kullanmalısınız.

Şablonun kendisi düzenli sembollerden ve özel yapılardan oluşur. Örneğin, normal satırlardaki "k" harfi kendisi anlamına gelir, ancak semboller "burada 0'dan 5'e kadar herhangi bir sayı olabilir" anlamına gelir. Özel karakterlerin tam listesi (php kılavuzunda bunlara meta karakterler denir) ve normal ifadedeki diğer tüm karakterler normaldir:

Aşağıda bu sembollerin her birinin anlamını analiz edeceğiz (ve ayrıca ilk ifadede "ё" harfinin neden ayrı işlendiğini de açıklayacağız), ama şimdilik normal ifadelerimizi metne uygulamaya çalışalım ve ne olduğunu görelim. Php, girdi olarak normal bir kalıp, bir metin ve boş bir dizi alan özel bir preg_match ($ regexp, $ text, $ match) işlevine sahiptir. Metnin, verilen modelle eşleşen bir alt dize içerip içermediğini kontrol eder ve değilse 0 veya varsa 1 döndürür. Ve indeks 0 olan elemanda geçirilen dizide, regex ile ilk bulunan eşleşme konur. Normal ifadeleri farklı dizgilere uygulayan basit bir program yazalım:

Örneği okuduktan sonra, düzenli ifadeleri daha detaylı inceleyelim.

Normal ifadelerde parantezler

Farklı parantez türlerinin ne anlama geldiğini tekrarlayalım:

  • Kıvrımlı ayraçlar a (1,5) önceki karakterin tekrar sayısını belirtir - bu örnekte, ifade 1 ila 5 ardışık "a" harfini arar
  • Köşeli parantezler "bu karakterlerden herhangi biri" anlamına gelir; bu durumda a, b, c, x, y, z harfleri veya 0 ile 5 arasındaki bir sayı. Diğer özel karakterler, örneğin | veya * - normal bir karakteri temsil ederler. ^ simgesi köşeli parantezlerin başındaysa, anlam tersine çevrilir: "belirtilenler dışında herhangi bir karakter" - örneğin [^ a-c], "a, b veya c dışında herhangi bir karakter" anlamına gelir.
  • Parantezler karakterleri ve ifadeleri gruplandırır. Örneğin, abc + ifadesinde artı işareti yalnızca c harfine atıfta bulunur ve bu ifade abc, abcc, abccc gibi kelimeleri arar. Ve eğer a (bc) + parantezlerini koyarsanız, artı niceleyicisi bc dizisini ifade eder ve ifade abc, abcbc, abcbcbc kelimelerini arar.

Not: Köşeli parantez içinde karakter aralıklarını belirtebilirsiniz, ancak Rus harfinin ё alfabesinden ayrı olduğunu ve "herhangi bir Rus harfini" yazmak için [a-yayo] yazmanız gerektiğini unutmayın.

Bexles

Diğer normal ifade eğitimlerine baktıysanız, muhtemelen ters eğik çizginin her yerde farklı yazıldığını fark etmişsinizdir. Bir yerde bir ters eğik çizgi yazarlar: \ d, ancak burada örneklerde 2 kez tekrarlanır: \\ d. Niye ya?

Normal ifade dili, ters eğik çizgiyi bir kez yazmanızı gerektirir. Ancak, PHP'de tek ve çift tırnaklı dizgelerde ters eğik çizginin özel bir anlamı vardır: dizgilerdeki kılavuz. Örneğin, $ x = "\ $" yazarsanız; daha sonra PHP bunu özel bir kombinasyon olarak yorumlayacak ve dizgeye yalnızca $ karakterini ekleyecektir (ve normal ifade motoru ondan önceki ters eğik çizgiyi bilmeyecek). \ $ dizisini bir dizgeye eklemek için ters eğik çizgiyi ikiye katlamalı ve kodu $ x = "\\ $"; ...

Bu nedenle, bazı durumlarda (bir karakter dizisinin PHP'de özel bir anlamı olduğu durumlarda) ters eğik çizgiyi ikiye katlamamız gerekir:

  • Normal ifadede \ $ yazmak için "\\ $" kodunu yazıyoruz
  • Normal ifadeye \\ yazmak için, her bir ters eğik çizgiyi ikiye katlarız ve "\\\\" yazarız
  • Normal ızgarada bir ters eğik çizgi ve bir sayı (\ 1) yazmak için ters eğik çizgi iki katına çıkarılmalıdır: "\\ 1"

Diğer durumlarda, bir veya iki ters eğik çizgi aynı sonucu verir: "\\ d" ve "\ d" dizeye bir çift \ d karakteri ekler - ilk durumda 2 ters eğik çizgi, ters eğik çizgi eklemek için bir dizidir, ikinci durumda özel bir sıra yoktur ve karakterler oldukları gibi eklenecektir. Dizeye hangi karakterlerin eklendiğini ve normal ifade motorunun echo ile ne gördüğünü kontrol edebilirsiniz: echo "\ $"; ... Evet, zor ama ne yapabilirsin?

Düzenli olarak özel yapılar

  • \ d herhangi bir rakamı arar, \ D - rakam dışında herhangi bir karakteri arar
  • \ w herhangi bir tek harf (herhangi bir alfabe), rakam veya alt çizgi _ ile eşleşir. \ W harf, sayı, alt çizgi dışında herhangi bir karakterle eşleşir.

Ayrıca, bir sözcük sınırını belirtmek için uygun bir koşul vardır: \ b. Bu yapı, bir tarafında harf / sayı / alt çizgi (\ w) olan bir karakter olması gerektiği ve diğer tarafında olmadığı anlamına gelir. Örneğin, metinde "kedi" kelimesini bulmak istiyoruz. Normal ifade / cat / ui yazarsak, bu harflerin sırasını herhangi bir yerde bulur - örneğin, "sığır" kelimesinin içinde. İstediğimiz bu değildi açıkçası. Normal ifadeye sınır koşulu kelimesini eklersek: / \ bcat \ b / ui, o zaman şimdi sadece ayrı "cat" kelimesi aranacaktır.

Manuel

  • PHP Normal İfade Sözdizimi, Ayrıntılı Açıklama