JavaScript'te iki dize arasında bir dize almak için normal ifade
Vakaların büyük çoğunluğunda çalışacak en eksiksiz çözüm, tembel nokta eşleştirme modeline sahip bir yakalama grubu kullanmaktır . Bununla birlikte, JavaScript normal ifadesindeki bir nokta satır sonu karakterleriyle eşleşmediğinden,% 100 durumda işe yarayacak olan bir veya.
[^]
[\s\S]
/ [\d\D]
/[\w\W]
.
ECMAScript 2018 ve daha yeni uyumlu çözüm
Destekleyen JavaScript ortamlarında ECMAScript 2018 , s
değiştirici verir.
satır sonu grafikleri de dahil olmak üzere herhangi bir karakterle eşleşmeyi ve normal ifade motoru değişken uzunluktaki görünümleri destekler. Yani, şöyle bir regex kullanabilirsiniz
var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional
Her iki durumda da, mevcut konum cow
daha sonra 1/0 veya daha fazla boşluklacow
, ardından mümkün olduğunca az 0+ karakter eşleştirilir ve tüketilir (= eşleşme değerine eklenir) ve sonra milk
(herhangi biriyle 1/0 veya daha fazla beyaz boşluktan önce).
Senaryo 1: Tek satır giriş
Bu ve aşağıdaki diğer tüm senaryolar tüm JavaScript ortamları tarafından desteklenir. Yanıtın altındaki kullanım örneklerine bakın.
cow (.*?) milk
cow
önce bir boşluk, sonra bir boşluk, daha sonra *?
tembel bir nicelleştirici olabildiğince az olan satır sonu karakterleri dışındaki 0+ karakterleri Grup 1'de yakalanır ve ardından bir boşluk milk
takip etmelidir (ve bunlar eşleştirilir ve tüketilen da ).
Senaryo 2: Çok satırlı giriş
cow ([\s\S]*?) milk
Buraya, cow
ve önce bir boşluk eşleştirilir, ardından mümkün olan en az 0+ karakter Grup 1 ile milk
eşleştirilir ve ardından bir boşluk eşleştirilir.
Senaryo 3: Çakışan eşleşmeler
Eğer gibi bir dize varsa >>>15 text>>>67 text2>>>
ve siz aradaki-2 eşleşmeleri almak gerekir >>>
+number
+ whitespace
ve >>>
sen kullanamazsınız, />>>\d+\s(.*?)>>>/g
nedeni sadece 1 maç bulacaksınız bu şekilde >>>
daha önce 67
zaten edilir tüketilen ilk maçı bulduktan sonra. Metin varlığını gerçekte "gevşetmeden" kontrol etmek için pozitif bir ileriye bakma kullanabilirsiniz (örn. Maça ekleme):
/>>>\d+\s(.*?)(?=>>>)/g
Bkz gösteri Online düzenli ifade veren text1
vetext2
Grup olarak 1 içerikler bulundu.
Ayrıca bkz . Bir dize için çakışan tüm eşleşmeleri nasıl edinirim .
Performans hususları
.*?
Normal ifade desenlerindeki tembel nokta eşleme deseni ( ), çok uzun bir giriş verilirse kod yürütülmesini yavaşlatabilir. Birçok durumda, döngü çözme tekniği daha büyük ölçüde yardımcı olur. Arasındaki tüm kapmak için çalışılıyor cow
ve milk
gelen "Their\ncow\ngives\nmore\nmilk"
biz sadece ile başlamayan tüm satırları eşleşmesi gerekir görüyoruz milk
yerine, böylece cow\n([\s\S]*?)\nmilk
biz kullanabilirsiniz:
/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm
Regex demosuna bakın (varsa \r\n
, kullanın /cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
). Bu küçük test dizgisi ile performans artışı göz ardı edilebilir, ancak çok büyük metinlerde farkı hissedeceksiniz (özellikle satırlar uzunsa ve satır sonları çok sayıda değilse).
JavaScript'te örnek regex kullanımı:
//Single/First match expected: use no global modifier and access match[1]
console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]);
// Multiple matches: get multiple matches with a global modifier and
// trim the results if length of leading/trailing delimiters is known
var s = "My cow always gives milk, thier cow also gives milk";
console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);}));
//or use RegExp#exec inside a loop to collect all the Group 1 contents
var result = [], m, rx = /cow (.*?) milk/g;
while ((m=rx.exec(s)) !== null) {
result.push(m[1]);
}
console.log(result);
Modern String#matchAll
yöntemi kullanma
const s = "My cow always gives milk, thier cow also gives milk";
const matches = s.matchAll(/cow (.*?) milk/g);
console.log(Array.from(matches, x => x[1]));