Sınırlayıcıları HARİÇ EDERKEN iki karakter arasında bir dize bulmak için Normal İfade


295

Ben bir dizeden ayırıcılar kendilerini döndürmeden, iki sınırlayıcılar arasında bulunan bir dizi karakter ayıklamak gerekir.

Basit bir örnek yardımcı olacaktır:

Hedef : Köşeli parantezleri, köşeli parantezler arasında döndürmeden köşeli parantezler arasında ayıklayın.

Temel dize :This is a test string [more or less]

Aşağıdaki reg. ex.

\ [. *? \]

Maç [more or less]. Sadece almam gerekiyor more or less(parantez olmadan).

Bunu yapmak mümkün mü?


Yanıtlar:


454

Kolay yapılır:

(?<=\[)(.*?)(?=\])

Teknik olarak, gözetleme ve gözetleme kullanıyor. Bkz. Lookahead ve Lookbehind Sıfır Genişlik İddiaları . Desen aşağıdakilerden oluşur:

  • öncesinde [yakalanmayan (arkası));
  • açgözlü olmayan bir yakalanmış grup. İlk başta durmak açgözlü değildir]; ve
  • ardından a] yakalanmadı (ileri).

Alternatif olarak, köşeli parantezler arasında olanları yakalayabilirsiniz:

\[(.*?)\]

ve tüm maç yerine ilk yakalanan grubu döndürür.


139
"Kolay yapılır", LOL! :) Düzenli ifadeler her zaman başım ağrıyor, sorunlarımı çözenleri bulur bulmaz onları unutmaya eğilimliyim. Çözümleriniz hakkında: Birincisi beklendiği gibi çalışıyor, ikincisi değil, köşeli parantezler dahil. C # kullanıyorum, belki RegEx nesnesi regex motor kendi "lezzet" vardır ...
Diego

5
Bunu yapıyor çünkü ilk eşleşen gruptan ziyade tüm maça bakıyorsunuz.
cletus

Çok teşekkürler, çok yararlı bir web sitesi! Referans olarak saklayacağım. :) Biraz karışıklık yaparsam özür dilerim, C # geliştirme gerçekten yeteneklerimden biri değil ..
Diego

1
Alt dize de sınırlayıcılar içeriyorsa bu işe yarar mı? Örneğin This is a test string [more [or] less]bu geri gelir more [or] lessmi?
gnzlbg

1
@gnzlbg hayır, "daha fazla [veya" döndürür
MerickOWA

53

Cletus tarafından sağlanan ilk çözüm olan JavaScript kullanıyorsanız, JavaScript lookbehind operatörünü desteklemediğinden çalışmaz.(?<=\[)(.*?)(?=\])

Ancak, ikinci çözüm iyi çalışır, ancak ikinci eşleşen öğeyi almanız gerekir.

Misal:

var regex = /\[(.*?)\]/;
var strToMatch = "This is a test string [more or less]";
var matched = regex.exec(strToMatch);

Geri dönecek:

["[more or less]", "more or less"]

Yani, ihtiyacınız olan ikinci değerdir. kullanın:

var matched = regex.exec(strToMatch)[1];

Geri vermek:

"more or less"

2
dizede [az çok] birden fazla eşleşme varsa ne olur?

Lookbehind iddiaları RegExp'e ES2018'de eklendi
TheDarkIn1978

19

Sadece parantezler arasındaki biti yakalamanız yeterlidir.

\[(.*?)\]

Yakalamak için parantez içine koyun. Bunun hangi dili kullandığını söylemiyorsunuz. Örneğin Perl'de buna $ 1 değişkenini kullanarak erişirsiniz.

my $string ='This is the match [more or less]';
$string =~ /\[(.*?)\]/;
print "match:$1\n";

Diğer diller farklı mekanizmalara sahip olacaktır. C #, örneğin, Maç koleksiyonu sınıfı kullanır inanıyorum.


Teşekkürler, ancak bu çözüm işe yaramadı, köşeli parantezleri de içeriyor. Cletus'un çözümüne yaptığım yorumda yazdığım gibi, C # RegEx nesnesi onu farklı şekilde yorumlayabilir. C # konusunda uzman değilim, bu yüzden sadece bir varsayım, belki de sadece benim bilgi eksikliğim. :)
Diego

11

[^\[] Olmayan herhangi bir karakteri eşleştirin.

+Eşleşmeyen her şeyin 1 veya daha fazlasını eşleştirin [. Bu eşleşmelerin gruplarını oluşturur.

(?=\])Olumlu bakış ]. Sonu olan bir grupla ]sonuca dahil etmeden eşleşir.

Bitti.

[^\[]+(?=\])

Kanıt.

http://regexr.com/3gobr

Null tarafından önerilen çözüme benzer. Ancak ek \]gerekli değildir. Ek bir not olarak, görünür \kaçmak için gerekli değildir [sonra ^. Okunabilirlik için içeri girerim.

Sınırlayıcıların aynı olduğu durumda çalışmaz. "more or less"Örneğin.


8

PHP:

$string ='This is the match [more or less]';
preg_match('#\[(.*)\]#', $string, $match);
var_dump($match[1]);


3

Ben bash komut dosyası ile regex kullanarak aynı sorunu vardı. Grep -o uygulayarak borular kullanarak 2 adımlı bir çözüm kullandım

 '\[(.*?)\]'  

önce, sonra

'\b.*\b'

Açıkçası diğer cevaplar kadar verimli değil, bir alternatif.


3

Bu özellikle javascript normal ifade ayrıştırıcı için çalışır /[^[\]]+(?=])/g

sadece konsolda çalıştır

var regex = /[^[\]]+(?=])/g;
var str = "This is a test string [more or less]";
var match = regex.exec(str);
match;

2

/ Ve # arasında bir dize bulmak istedim, ancak # bazen isteğe bağlıdır. İşte kullandığım normal ifade:

  (?<=\/)([^#]+)(?=#*)

0

İşte C # '[' ve ']' olmadan nasıl var:

        var text = "This is a test string [more or less]";
        //Getting only string between '[' and ']'
        Regex regex = new Regex(@"\[(.+?)\]");
        var matchGroups = regex.Matches(text);
        for (int i = 0; i < matchGroups.Count; i++)
        {
            Console.WriteLine(matchGroups[i].Groups[1]);
        }

Çıktı:

more or less

-1

Metni parantez olmadan ayıklamanız gerekirse, bash awk kullanabilirsiniz

echo " [hola mundo] " | awk -F'[][]' '{print $2}'

sonuç:

hola mundo

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.