Belirtilen dizeler dışında her şeyi eşleştir


120

Aşağıdaki normal ifadenin "kırmızı", "yeşil" veya "mavi" ile eşleşeceğini biliyorum.

red|green|blue

Belirtilen birkaç dize dışında her şeyi eşleştirmenin basit bir yolu var mı ?


1
Normal ifadelerin tüm çeşitleri bunu yapamaz. Hangi ortamda çalışıyorsun Java? Perl? .AĞ? Bazı C / C ++ regex kitaplığı? RDBMS mi?
FrustratedWithFormsDesigner

8
Ne için istediğini söylemiyorsun, ama "eşleştirme" işleminin anlamını tersine çevirebilirsin. Eşleşmeyen kısımlarda ayıklama yapmaya çalışıyorsanız bu size yardımcı olmayacaktır, ancak hariç tutulan bir dizenin mevcut olup olmadığını test etmek işe yarayacaktır: if (!s.match(/red|green|blue/)) ... Not: OP'nin hangi dili / çerçeveyi belirtmediğini biliyorum, bu yüzden önceki kısım, kuralcı değil genel bir örnek olarak düşünülmelidir.
tvanfosson

Yanıtlar:


154

Dizenin ne kırmızı, yeşil ne de mavi olmadığından emin olmak istiyorsanız, caskey'in cevabı budur. Bununla birlikte, genellikle istenen şey, çizginin hiçbir yerinde kırmızı, yeşil veya mavi içermediğinden emin olmaktır. Bunun için, normal ifadeyi negatif ilerleme ile sabitleyin ^ve ekleyin .*:

^(?!.*(red|green|blue))

Ayrıca, "motor" kelimesini içeren ancak bu renklerin hiçbirini içermeyen çizgiler istediğinizi varsayalım:

^(?!.*(red|green|blue)).*engine

.*Normal ifadenin başını çarpanlarına ayırabileceğinizi düşünebilirsiniz :

^.*(?!red|green|blue)engine     # Does not work

ama yapamazsın. .*Çalışması için her iki örneğe de sahip olmalısınız .


48

Dile bağlıdır, ancak genel olarak böyle ekleyebileceğiniz olumsuz iddialar vardır:

(?!red|green|blue)

(Sözdizimi düzeltmesi için teşekkürler, yukarıdaki geçerli Java ve Perl, YMMV'dir)


2
@caskey, Tam cevap, benim ve seninkinin birleşimidir. Onları bir araya getirmek isterseniz, benimkini sileceğim.
Wayne Conrad

14
Biraz açıklasanız bu cevap çok daha faydalı olur. Örneğin: "?" ve "!" anlamına gelmek? Neden yakalama gruplarına ihtiyacınız var?
Lii

Python da geçerli.
Joe Mornin

bunu sadece Delphi regEx kitaplığı ile kullandım ve yalnızca şu şekilde çalışır: ^ (?! red | green | blue). Ayrıca regex101.com'da test etmek için de geçerlidir . Öyleyse yukarıdaki bir yazım hatası ^ eksik mi yoksa Java / Perl / Python'da böyle mi çalışıyor?
Peter

33

Verilen Dizeler Dışında Her Şeyi Eşleştirme

Her şeyi eşleştirmek istediğiniz dizinin tamamını, ancak belirli dizeleri eşleştirmek istiyorsanız, bunu şu şekilde yapabilirsiniz:

^(?!(red|green|blue)$).*$

Bu, eşleşmeye dizenin başından başlayıp kırmızı, yeşil veya mavi ile başlayıp bitemeyeceği ve diğer herhangi bir şeyi dizenin sonuna kadar eşleştireceği anlamına gelir.

Burada deneyebilirsiniz: https://regex101.com/r/rMbYHz/2

Bunun yalnızca negatif bir önden okumayı destekleyen normal ifade motorlarıyla çalıştığını unutmayın .


23

Negatif bakış açısına ihtiyacınız yok. Çalışan bir örnek var:

/([\s\S]*?)(red|green|blue|)/g

Açıklama:

  • [\s\S] - herhangi bir karakterle eşleş
  • * - önceki gruptan 0 ile sınırsız arasında maç
  • ? - mümkün olduğunca az eşleştirin
  • (red|green|blue|) - bu kelimelerden biriyle eşleş ya da hiçbir şey
  • g - kalıbı tekrarla

Misal:

whiteredwhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredwhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredredgreenredgreenredgreenredgreenredgreenbluewhiteredbluewhiteredbluewhiteredbluewhiteredbluewhiteredwhite

Olacak:

whitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhite

Dene: regex101.com


4
Adım sayısını [\ s \ S] yerine nokta koyarak önemli ölçüde azaltabilirsiniz. Neden görünüşe göre diğer her örneğin her kelimeyi ayrı ayrı yakaladığı kafam çok karışmıştı. Bu yol biraz daha normal ifade adımıdır, ancak çok daha az son işlem gerektirir.
Zatronium

3
ancak bu eşleştirme (metin doğrulama) yapmaz, sadece değiştirme sırasında belirtilen metni kaldırır.
Marek R

Bu çözüm, bilinen sözcüklerden sonraki son metin yığınını çıkarmaz. Yani hızı karşılaştırmaya gerek yok, sadece yanlış.
Wiktor Stribiżew

@ WiktorStribiżew düzeltildi.
hlcs

10

Aynı soruyu sordum, önerilen çözümler neredeyse işe yarıyordu ama bazı sorunları vardı. Sonunda kullandığım normal ifade:

^(?!red|green|blue).*

Javascript ve .NET ile test ettim.

. * negatif önden şu şekilde yerleştirilmemelidir: ^ (?!. * red | green | blue) veya bu, ilk elemanın diğerlerinden farklı davranmasını sağlar (yani "anotherred", süre eşleşmez. " othergreen "olur)


3

Herhangi bir metni eşleştiren ancak bir kalıpla eşleşenleri genellikle dizeyi normal ifade kalıbıyla ayırarak elde edilir .

Örnekler :

  • - Regex.Split(text, @"red|green|blue")veya boş değerlerden kurtulmak için Regex.Split(text, @"red|green|blue").Where(x => !string.IsNullOrEmpty(x))( demoya bakın )
  • - Regex.Split(text, "red|green|blue")veya boş öğeleri kaldırmak için Regex.Split(text, "red|green|blue").Where(Function(s) Not String.IsNullOrWhitespace(s))( demoya veya LINQ'nun desteklendiği bu demoya bakın )
  • - text.split(/red|green|blue/)( gburada değiştirici kullanmaya gerek yok!) (boş değerlerden kurtulmak için kullanın text.split(/red|green|blue/).filter(Boolean)), demoya bakın
  • - text.split("red|green|blue")veya - sondaki tüm boş öğeleri tutmak için - kullanın text.split("red|green|blue", -1)veya tüm boş öğeleri kaldırmak için bunları kaldırmak için daha fazla kod kullanın ( demoya bakın )
  • - Java'ya benzer şekilde, text.split(/red|green|blue/)sondaki tüm öğeleri kullanmak text.split(/red|green|blue/, -1)ve tüm boş öğeleri kaldırmak için kullanın text.split(/red|green|blue/).findAll {it != ""})( demoya bakın )
  • - text.split(Regex("red|green|blue"))veya boş öğeleri kaldırmak için kullanın text.split(Regex("red|green|blue")).filter{ !it.isBlank() }, demoya bakın
  • - text.split("red|green|blue")veya sondaki tüm boş öğeleri saklamak için kullanın text.split("red|green|blue", -1)ve tüm boş öğeleri kaldırmak için kullanın text.split("red|green|blue").filter(_.nonEmpty)( demoya bakın )
  • - text.split(/red|green|blue/), boş değerlerden kurtulmak için kullanın .split(/red|green|blue/).reject(&:empty?)(ve hem baştaki hem de sondaki boş öğeleri almak -1için ikinci bağımsız değişken olarak kullanın .split(/red|green|blue/, -1)) ( demoya bakın )
  • - my @result1 = split /red|green|blue/, $text;veya sondaki tüm boş öğelerle my @result2 = split /red|green|blue/, $text, -1;veya boş öğeler olmadan my @result3 = grep { /\S/ } split /red|green|blue/, $text;( demoya bakın )
  • - preg_split('~red|green|blue~', $text)veya preg_split('~red|green|blue~', $text, -1, PREG_SPLIT_NO_EMPTY)boş öğe çıkmaması için ( demoya bakın )
  • - re.split(r'red|green|blue', text)veya boş öğeleri kaldırmak için list(filter(None, re.split(r'red|green|blue', text)))( demoya bakın )
  • - Kullanın regexp.MustCompile("red|green|blue").Split(text, -1)ve boş öğeleri kaldırmanız gerekirse bu kodu kullanın . Demoya gidin .

NOT : Eğer desenler içeriyorsa yakalama gruplarını , regex bölünmüş işlevleri / yöntemleri olabilir ayrıca ek seçeneklere bağlı olarak farklı davranır. Lütfen daha sonra uygun bölünmüş yöntem belgelerine bakın.


0

"Kırmızı" kelimesi hariç tümü

var href = '(text-1) (red) (text-3) (text-4) (text-5)';

var test = href.replace(/\((\b(?!red\b)[\s\S]*?)\)/g, testF); 

function testF(match, p1, p2, offset, str_full) {
  p1 = "-"+p1+"-";
  return p1;
}

console.log(test);

"Kırmızı" kelimesi hariç tümü

var href = '(text-1) (frede) (text-3) (text-4) (text-5)';

var test = href.replace(/\(([\s\S]*?)\)/g, testF); 

function testF(match, p1, p2, offset, str_full) {
  p1 = p1.replace(/red/g, '');
  p1 = "-"+p1+"-";
  return p1;
}

console.log(test);

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.