Açgözlü olmayana düzenli ifade nasıl yapılır?


227

JQuery kullanıyorum. Özel karakter (başlangıç ​​ve bitiş) bir blok ile bir dize var. O özel karakter bloğundan metin almak istiyorum. Dize içi bulma için normal ifade nesnesi kullandım. Ancak jQuery'ye iki veya daha fazla özel karakter olduğunda birden fazla sonuç bulmasını nasıl söyleyebilirim?

HTML kodum:

<div id="container">
    <div id="textcontainer">
     Cuc chiến pháp lý gia [|cơ thử|nghim|] th trường [|test2|đây là test ln 2|] chng khoán [|Mỹ|day la nuoc my|] và ngân hàng đầu tư quyn lc nht Ph Wall mi ch bt đầu.
    </div>
</div>

ve JavaScript kodum:

$(document).ready(function() {
  var takedata = $("#textcontainer").text();
  var test = 'abcd adddb';
  var filterdata = takedata.match(/(\[.+\])/);

  alert(filterdata); 

  //end write js 
});

Benim sonucum : [| cơ th ng | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc my |] . Ama bu istediğim sonuç değil :(. 1 kez [metin] ve 2 kez [demo] nasıl alınır?


İnternette bilgi aradıktan sonra işimi yaptım ^^. Ben böyle kod yapmak:

var filterdata = takedata.match(/(\[.*?\])/g);
  • benim sonucum : [| cơ thử | nghiệm |], [| test2 | đây là test lần 2 |] bu doğru !. ama bunu gerçekten anlamıyorum. Nedenime cevap verebilir misin?

Yanıtlar:


492

Açgözlü olmayan normal ifade düzenleyicileri, açgözlü karşı parçaları gibidir, ancak ?hemen ardından:

*  - zero or more
*? - zero or more (non-greedy)
+  - one or more
+? - one or more (non-greedy)
?  - zero or one
?? - zero or one (non-greedy)

29
?kendi başına 'bir veya sıfır' anlamına geldiğini belirtmek yararlı olabilir (ama açgözlüdür!). Örneğin 'bb'.replace(/b?/, 'a') //'ab've'bb'.replace(/c?/, 'a') //'abb'
Hashbrown

1
c orada hiçbir şeyle nasıl eşleşmedi
Muhammed Umer

1
Onun yüzünden almayı öneriyorum düşünüyorum @MuhammadUmer cuymayacak, bununla birlikte ne kadar ?, hangi 0 or 1, o zaman eşleşecek şekilde oluyor 0 number of c charactersdolayısıyla onun yerine. Nasıl çalıştığına dair hiçbir fikrim yok, çünkü denediğim herhangi bir regex motorunda derlenmiyor 😢
Noctis

35

Açgözlülüğün bir sorun olduğu konusunda haklısınız:

--A--Z--A--Z--
  ^^^^^^^^^^
     A.*Z

Her iki eşleşme istiyorsanız A--Z, kullanmak zorundayız A.*?Z( ?yapar *"isteksiz", ya da tembel).

Bununla birlikte, bazen bunu yapmanın daha iyi yolları vardır, örn.

A[^Z]*+Z

Bu, geri izlemeyi azaltmak için negatif karakter sınıfı ve sahip olunan nicelik belirteci kullanır ve daha verimli olması muhtemeldir.

Sizin durumunuzda, normal ifade şöyle olacaktır:

/(\[[^\]]++\])/

Ne yazık ki Javascript regex iyelik belirleyiciyi desteklemediğinden, sadece aşağıdakilerle ilgilisiniz:

/(\[[^\]]+\])/

Ayrıca bakınız


Hızlı özet

*   Zero or more, greedy
*?  Zero or more, reluctant
*+  Zero or more, possessive

+   One or more, greedy
+?  One or more, reluctant
++  One or more, possessive

?   Zero or one, greedy
??  Zero or one, reluctant
?+  Zero or one, possessive

İsteksiz ve iyelik niceliklerinin sonlu tekrar {n,m}yapılarına da uygulanabileceğini unutmayın .

Java'daki örnekler:

System.out.println("aAoZbAoZc".replaceAll("A.*Z", "!"));  // prints "a!c"
System.out.println("aAoZbAoZc".replaceAll("A.*?Z", "!")); // prints "a!b!c"

System.out.println("xxxxxx".replaceAll("x{3,5}", "Y"));  // prints "Yx"
System.out.println("xxxxxx".replaceAll("x{3,5}?", "Y")); // prints "YY"

regex'i işime kopyalarım ve sonuç: geçersiz niceleyici + \]) [Bu hatayı kes] var filterdata = takedata.match (/ (\ [[^ \]] ++ \]) /); \ n ( firebugs + Firefox) yanlış bir şey mi?
Rueta

@Rueta: Görünüşe göre Javascript lezzeti iyelik özelliğini desteklemiyor. Cevabımı bu gerçeği yansıtacak şekilde düzenledim. +İki yerine bir tane kullanabilirsiniz .
poligeno

1
Atom grupları iyelik nicelleştiriciler yerine kullanılabilse de, JavaScript atom gruplarını da desteklemez. Ancak üçüncü bir alternatif var, buna bakın: instanceof.me/post/52245507631/… -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
Roland Pihlakas

2
Bu bir JavaScript sorusu ve Java! = JavaScript için bir Java cevabıdır. Okuyucular, not alın.
Roshambo

3

Bunun böyle olacağına inanıyorum

takedata.match(/(\[.+\])/g);

gİlk maçında durmaz böylece sonunda, küresel gelir.


Evet, / g'de haklısın. Ben sadece cevap / g ^^ ile işimi yaptım. Ama düzenli yaptığımda /(\[.+\ Cialis)/g Sonuç: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc benim |] :(
Rueta
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.