Bir JavaScript normal ifadesinde eşleşen gruplara nasıl erişirsiniz?


1368

Düzenli bir ifade kullanarak bir dizenin bir bölümünü eşleştirmek ve sonra o parantez alt dizeye erişmek istiyorum:

var myString = "something format_abc"; // I want "abc"

var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);

console.log(arr);     // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]);  // Prints: undefined  (???)
console.log(arr[0]);  // Prints: format_undefined (!!!)

Neyi yanlış yapıyorum?


Yukarıdaki normal ifade kodu ile yanlış bir şey olduğunu keşfettim: karşı test edildi gerçek dize:

"date format_%A"

"% A" undefined olduğunu bildirmek çok garip bir davranış gibi görünüyor, ancak doğrudan bu soru ile ilgili değil, bu yüzden yeni bir tane açtım , JavaScript'te neden "undefined" döndüren eşleşen bir alt dize? .


Sorun, console.logparametrelerini bir printfifade gibi almasıydı ve logging ( "%A") dizesinin özel bir değeri olduğundan, bir sonraki parametrenin değerini bulmaya çalışıyordu.

Yanıtlar:


1674

Bunun gibi çekim gruplarına erişebilirsiniz:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc

Ve birden fazla eşleşme varsa, bunları tekrarlayabilirsiniz:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
  // matched text: match[0]
  // match start: match.index
  // capturing group n: match[n]
  console.log(match[0])
  match = myRegexp.exec(myString);
}

Düzenleme: 2019-09-10

Gördüğünüz gibi, birden fazla maçta tekrarlamanın yolu çok sezgisel değildi. Bu String.prototype.matchAllyöntemin önerisine yol açar . Bu yeni yöntemin ECMAScript 2020 şartnamesinde gönderilmesi beklenmektedir . Bize temiz bir API sağlar ve birden fazla sorunu çözer. Chrome 73+ / Node 12+ ve Firefox 67+ gibi büyük tarayıcılara ve JS motorlarına ulaşmaya başladı.

Yöntem bir yineleyici döndürür ve aşağıdaki gibi kullanılır:

const string = "something format_abc";
const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
const matches = string.matchAll(regexp);
    
for (const match of matches) {
  console.log(match);
  console.log(match.index)
}

Bir yineleyici döndürdüğünden, tembel olduğunu söyleyebiliriz, bu özellikle çok sayıda yakalama grubunu veya çok büyük dizeleri işlerken yararlıdır. Ancak ihtiyacınız varsa, sonuç forma sözdizimi veya Array.fromyöntem kullanılarak kolayca bir Array'a dönüştürülebilir :

function getFirstGroup(regexp, str) {
  const array = [...str.matchAll(regexp)];
  return array.map(m => m[1]);
}

// or:
function getFirstGroup(regexp, str) {
  return Array.from(str.matchAll(regexp), m => m[1]);
}

Bu arada, bu teklif daha geniş bir destek alırken, resmi şim paketini kullanabilirsiniz .

Ayrıca, yöntemin iç işleri basittir. Bir jeneratör işlevi kullanan eşdeğer bir uygulama aşağıdaki gibi olacaktır:

function* matchAll(str, regexp) {
  const flags = regexp.global ? regexp.flags : regexp.flags + "g";
  const re = new RegExp(regexp, flags);
  let match;
  while (match = re.exec(str)) {
    yield match;
  }
}

Orijinal normal ifadenin bir kopyası oluşturulur; bu, lastIndexçoklu eşlemelerden geçerken mülkün mutasyonundan kaynaklanan yan etkilerden kaçınmaktır .

Ayrıca, sonsuz döngüden kaçınmak için normal ifadenin global bayrağa sahip olduğundan emin olmamız gerekir .

Ayrıca, bu StackOverflow sorusunun bile teklifin tartışmalarında referans verildiğini görmekten memnuniyet duyuyorum .


114
+1 Lütfen ikinci örnekte RegExp nesnesini kullanmanız gerektiğini unutmayın (yalnızca "/ myregexp /" değil), çünkü nesnede lastIndex değerini tutar.
Regexp

7
@ianaz: Bunun doğru olduğuna inanmıyorum? http://jsfiddle.net/weEg9/ en azından Chrome üzerinde çalışıyor gibi görünüyor.
spinningarrow

16
Neden yerine yukarıda yapın: var match = myString.match(myRegexp); // alert(match[1])?
JohnAllen

29
Açık "yeni RegExp" gerekmez, ancak / g belirtilmedikçe sonsuz döngü oluşur
George C

4
Sonsuz döngüye girmemenin başka bir yolu da dize açık bir şekilde güncellemektir, örneğinstring = string.substring(match.index + match[0].length)
Olga

186

Burada almak için kullanabileceğiniz bir yöntem var n her maç için grup yakalama inci:

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);


12
Bu, diğerlerine karşı çok üstün bir cevap çünkü tek bir maç yerine tüm maçlar üzerinde doğru bir şekilde yineleme gösteriyor.
Rob Evans

13
mnn haklı. Eğer 'g' bayrağı yoksa bu sonsuz bir döngü oluşturur. Bu işleve çok dikkat edin.
Druska

4
Bunu python's re.findall () ile benzer hale getirmek için geliştirdim. Tüm eşleşmeleri bir dizi dizide gruplandırır. Ayrıca, genel değiştirici sonsuz döngü sorununu giderir. jsfiddle.net/ravishi/MbwpV
ravishi

5
@MichaelMikowski şimdi sonsuz döngünüzü gizlediniz, ancak kodunuz yavaş çalışacak. Kötü bir şekilde kod kırmanın daha iyi olduğunu, bu yüzden geliştirme sırasında yakalamanızı savunuyorum. Bazı bs maksimum yinelemelerin girilmesi özensizdir. Sorunları kök nedenlerini düzeltmek yerine gizlemek cevap değildir.
wallacer

4
@MichaelMikowski, yürütme sınırına ulaşmadığınızda anlamlı derecede yavaş değil. Siz olduğunuzda, açıkça çok daha yavaştır. Kodunuzun işe yaramadığını söylemiyorum, pratikte bunun yarardan çok zarar vereceğini düşünüyorum. Bir geliştirme ortamında çalışan insanlar, bazı kod yığınlarının 10.000 gereksiz çalıştırılmasına rağmen kodun yüksüz çalıştığını görürler. Daha sonra bir üretim ortamına itecekler ve uygulamalarının neden yük altında kaldığını merak edecekler. Deneyimlerime göre, işler bariz bir şekilde ve daha erken geliştirme döngüsünde kırılırsa daha iyidir.
wallacer

58

var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);

\bTam olarak aynı şey değildir. (Çalışıyor --format_foo/, ama çalışmıyor format_a_b) Ama ifadenize bir alternatif göstermek istedim, ki bu iyi. Tabii ki, matchçağrı önemli şeydir.


2
Tam tersi. '\ b' kelimeleri sınırlar. word = '\ w' = [a-zA-Z0-9_]. "format_a_b" bir kelimedir.
BF

1
@BFHonestly, format_a_b6 yıl önce bir düşünce olarak " üzerinde çalışmaz" diye ekledim ve orada ne demek istediğimi hatırlamıyorum ... :-) Sanırım " asadece yakalamak için çalışmıyor ", yani. sonraki ilk alfabetik bölüm format_.
PhiLho

1
Ben \ b (- format_foo /} \ b "--format_foo /" dönmediğini söylemek istedim çünkü "-" ve "/" hiçbir \ word karakteri değildir. Ama \ b (format_a_b) \ b "format_a_b döndürür ". Doğru? Yuvarlak ifadeli metin ifadenize atıfta bulunuyorum. (Aşağı oy vermedi!)
BF

31

Yukarıdaki çok eşleşmeli parantez örnekleri ile ilgili olarak, istediğimi elde etmedikten sonra burada bir cevap arıyordum:

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

Yukarıda ve .push () ile biraz kıvrımlı işlev çağrılarına baktıktan sonra, sorunun mystring.replace () ile çok zarif bir şekilde çözülebileceği konusunda şaşkına döndü (değiştirme noktası DEĞİL ve hatta yapılmadı bile , CLEAN, ikinci parametre için dahili özyinelemeli fonksiyon çağrısı seçeneği!):

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );

Bundan sonra, bir daha hiç bir şey için .match () kullanacağımı sanmıyorum.


26

Son fakat en az değil, benim için iyi çalışan bir kod satırı buldum (JS ES6):

let reg = /#([\S]+)/igm; // Get hashtags.
let string = 'mi alegría es total! ✌🙌\n#fiestasdefindeaño #PadreHijo #buenosmomentos #france #paris';

let matches = (string.match(reg) || []).map(e => e.replace(reg, '$1'));
console.log(matches);

Bu geri dönecektir:

['fiestasdefindeaño', 'PadreHijo', 'buenosmomentos', 'france', 'paris']

1
BOOM! Budur burada en zarif çözüm. Bunu Alexz'in tam yaklaşımından daha iyi buldum, çünkü bu daha az ileriye dönük ve daha fazla sonuç için daha zarif. İyi iş çıkardın Sebastien H.replace
Cody

Bu o kadar iyi çalışıyor ki kesinlikle benim araçlarıma gidiyor :)
Cody

1
@Cody haha ​​teşekkürler dostum!
Sebastien H.

19

Bu cevapta kullanılan terminoloji:

  • Maç şöyle dizenizle karşı RegEx desen çalışan sonucunu gösterir: someString.match(regexPattern).
  • Eşleşen desenler , giriş dizesinin, eşleşen dizinin içinde bulunan tüm eşleşen bölümlerini gösterir . Bunların tümü, giriş dizesinin içindeki modelinizin örnekleridir.
  • Eşleşen gruplar , RegEx modelinde tanımlanan yakalanacak tüm grupları belirtir. (Parantez içindeki kalıplar /format_(.*?)/g, (.*?)şöyle : Eşleşen bir grup olacaktır.) Bunlar eşleşen kalıplarda bulunur .

Açıklama

Eşleşen gruplara erişmek için, eşleşen desenlerin her birinde , eşleşme üzerinde yinelenen bir işleve veya benzeri bir şeye ihtiyacınız vardır . Diğer yanıtların birçoğunun gösterdiği gibi, bunu yapmanın birkaç yolu vardır. Diğer yanıtların çoğu , eşleşen tüm kalıpları yinelemek için bir while döngüsü kullanır , ancak bence bu yaklaşımdaki potansiyel tehlikeleri biliyoruz. new RegExp()Sadece bir yorumda bahsedilen sadece kalıbın kendisi ile eşleşmek gerekir . Bunun nedeni, .exec()yöntemin bir jeneratör işlevine benzer şekilde davranmasıdır - her eşleşme olduğunda durur , ancak bir .lastIndexsonraki .exec()çağrıda oradan devam etmesini sağlar .

Kod örnekleri

Aşağıda, eşleşen tüm desenlerden birini searchStringdöndüren bir işlev örneği verilmiştir ; burada her biri , eşleşen tüm gruplarla birdir . While döngüsü kullanmak yerine, hem işlevi hem de daha performanslı bir yolla örnekler verdim - düz- döngü kullanarak .ArraymatchArrayArray.prototype.map()for

Kısa versiyonlar (daha az kod, daha sözdizimsel şeker)

Temelde forEachdaha hızlı- fordöngü yerine bir- döngü uyguladığından bunlar daha az performans gösterir.

// Concise ES6/ES2015 syntax
const searchString = 
    (string, pattern) => 
        string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match => 
            new RegExp(pattern.source, pattern.flags)
            .exec(match));

// Or if you will, with ES5 syntax
function searchString(string, pattern) {
    return string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match =>
            new RegExp(pattern.source, pattern.flags)
            .exec(match));
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

Performanslı versiyonlar (daha fazla kod, daha az sözdizimsel şeker)

// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
    let result = [];

    const matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (let i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
};

// Same thing, but with ES5 syntax
function searchString(string, pattern) {
    var result = [];

    var matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (var i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

Bu alternatifleri daha önce diğer cevaplarda belirtilenlerle karşılaştırmadım, ancak bu yaklaşımın diğerlerinden daha az performans ve daha az başarısızlık olduğundan şüpheliyim.


19

String#matchAll( Aşama 3 Taslağı / 7 Aralık 2018 teklifine bakın ), maç nesnesindeki tüm gruplara erişimi kolaylaştırır (Grup 0'ın tüm maç olduğunu unutmayın, diğer gruplar da kalıptaki yakalama gruplarına karşılık gelir):

İle matchAllmevcuttur, sen önleyebilirsiniz whiledöngü ve execile /g... Bunun yerine, kullanarak matchAll, size daha uygun kullanabileceğiniz bir yineleyici geri almak for...of, dizi yayılması veya Array.from()yapılara

Bu yöntem , PHP'de Python'da Regex.MatchesC # ' a benzer bir çıktı verir .re.finditerpreg_match_all

Bir JS demosuna bakın (Google Chrome 73.0.3683.67 (resmi derleme), beta (64 bit) ile test edilmiştir):

var myString = "key1:value1, key2-value2!!@key3=value3";
var matches = myString.matchAll(/(\w+)[:=-](\w+)/g);
console.log([...matches]); // All match with capturing group values

console.log([...matches])gösterileri

resim açıklamasını buraya girin

Ayrıca, eşleşme değerini veya belirli grup değerlerini kullanarak

let matchData = "key1:value1, key2-value2!!@key3=value3".matchAll(/(\w+)[:=-](\w+)/g)
var matches = [...matchData]; // Note matchAll result is not re-iterable

console.log(Array.from(matches, m => m[0])); // All match (Group 0) values
// => [ "key1:value1", "key2-value2", "key3=value3" ]
console.log(Array.from(matches, m => m[1])); // All match (Group 1) values
// => [ "key1", "key2", "key3" ]

NOT : Tarayıcı uyumluluk ayrıntılarına bakın.


Anahtar / değer çiftleri için mükemmel örnek. Özlü ve okunması kolay, kullanımı çok basit. Ayrıca, daha iyi hata işleme, forma null yerine boş bir dizi döndürür, bu yüzden daha fazla 'hatası, null özelliği "uzunluğu" yok
Jarrod McGuire

17

Sözdiziminiz muhtemelen en iyisi değildir. FF / Gecko, RegExp'i bir İşlev uzantısı olarak tanımlar.
(FF2 ileri gitti typeof(/pattern/) == 'function')

Bu FF'ye özgü görünüyor - IE, Opera ve Chrome hepsi bunun için istisnalar atıyor.

Bunun yerine, daha önce başkaları tarafından belirtilen yöntemlerden birini kullanın: RegExp#execveya String#match.
Aynı sonuçları sunarlar:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

16

execYöntemi çağırmaya gerek yok ! "Match" yöntemini doğrudan dizede kullanabilirsiniz. Parantezleri unutmayın.

var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...

Konum 0, tüm sonuçları içeren bir dize içerir. Konum 1, parantez ile temsil edilen ilk eşleşmeye ve konum 2, parantezlerinizde izole edilen ikinci eşleşmeye sahiptir. İç içe parantezler zor, bu yüzden dikkat!


4
Global bayrak olmadan bu tüm maçları döndürür, bununla birlikte, sadece bir büyük bir tane alırsınız, bu yüzden buna dikkat edin.
Shadymilkman01

8

Sadece tek bir paranteziniz varsa pratik olan tek bir astar:

while ( ( match = myRegex.exec( myStr ) ) && matches.push( match[1] ) ) {};

4
Neden olmasınwhile (match = myRegex.exec(myStr)) matches.push(match[1])
willlma

7

Kodunuzu kullanma:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

Düzenleme: Safari 3, önemliyse.


7

Es2018 ile artık String.match()adlandırılmış gruplarla yapabilirsiniz, normal ifadenizi ne yapmaya çalıştığı konusunda daha açık hale getirir.

const url =
  '/programming/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression?some=parameter';
const regex = /(?<protocol>https?):\/\/(?<hostname>[\w-\.]*)\/(?<pathname>[\w-\./]+)\??(?<querystring>.*?)?$/;
const { groups: segments } = url.match(regex);
console.log(segments);

ve böyle bir şey alacaksın

{protokol: "https", ana makine adı: "stackoverflow.com", yol adı: "sorular / 432493 / javascript-normal ifadesinde eşleşen gruplara nasıl erişirsiniz", querystring: " bazı = parametresi "}


6

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'Rs.200 is Debited to A/c ...2031 on 02-12-14 20:05:49 (Clear Bal Rs.66248.77) AT ATM. TollFree 1800223344 18001024455 (6am-10pm)';
var myRegEx = /clear bal.+?(\d+\.?\d{2})/gi;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);

function getMatches(string, regex, index) {
  index || (index = 1); // default to the first capturing group
  var matches = [];
  var match;
  while (match = regex.exec(string)) {
    matches.push(match[index]);
  }
  return matches;
}


// Example :
var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);

// Log results
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))
console.log(matches);


3

Regex muhtemelen olması gerektiğini PhiLo kabul bile kodunuz benim için (Mac FF3) çalışır :

/\bformat_(.*?)\b/

(Ama elbette emin değilim çünkü regex'in bağlamını bilmiyorum.)


1
boşluk ayrılmış bir liste bu yüzden iyi olacağını düşündüm. bu kodun benim için çalışmadığını garip (FF3 Vista)
nickf

1
Evet, gerçekten garip. Firebug konsolunda kendi başına denediniz mi? Aksi halde boş bir sayfadan demek istiyorum.
PEZ

2
/*Regex function for extracting object from "window.location.search" string.
 */

var search = "?a=3&b=4&c=7"; // Example search string

var getSearchObj = function (searchString) {

    var match, key, value, obj = {};
    var pattern = /(\w+)=(\w+)/g;
    var search = searchString.substr(1); // Remove '?'

    while (match = pattern.exec(search)) {
        obj[match[0].split('=')[0]] = match[0].split('=')[1];
    }

    return obj;

};

console.log(getSearchObj(search));

2

Birden fazla eşleşmeyi ayrıştırmak için gerçekten açık bir döngüye ihtiyacınız yoktur - bir ikame işlevini şu şekilde açıklandığı gibi ikinci argüman olarak iletin String.prototype.replace(regex, func):

var str = "Our chief weapon is {1}, {0} and {2}!"; 
var params= ['surprise', 'fear', 'ruthless efficiency'];
var patt = /{([^}]+)}/g;

str=str.replace(patt, function(m0, m1, position){return params[parseInt(m1)];});

document.write(str);

m0Argüman tam Eşleşen alt temsil eder {0}, {1}vb m1yani düzenli ifade parantez içine kısmen eşleşen ilk grubunu temsil eder, 0ilk maçı için. Ve positionbu durumda kullanılmayan dizenin bulunduğu dizenin içindeki başlangıç ​​dizinidir.


1

Eşleşen gruba, ardından ters eğik çizgi ve ardından eşleşen grup sayısını kullanarak düzenli ifadelerde erişebiliriz:

/([a-z])\1/

\ 1 kodunda birinci grupla eşleşti ([az])


1

Tek hat çözümü:

const matches = (text,regex) => [...text.matchAll(regex)].map(([match])=>match)

Böylece şu şekilde kullanabilirsiniz (/ g kullanmalısınız):

matches("something format_abc", /(?:^|\s)format_(.*?)(?:\s|$)/g)

sonuç:

[" format_abc"]

0

Tüm grup oluşumunu al

let m=[], s = "something format_abc  format_def  format_ghi";

s.replace(/(?:^|\s)format_(.*?)(?:\s|$)/g, (x,y)=> m.push(y));

console.log(m);


0

Ben benim gibisin ve regex böyle bir Nesne dönmek isterdim:

{
    match: '...',
    matchAtIndex: 0,
    capturedGroups: [ '...', '...' ]
}

sonra işlevi aşağıdan kesin

/**
 * @param {string | number} input
 *          The input string to match
 * @param {regex | string}  expression
 *          Regular expression 
 * @param {string} flags
 *          Optional Flags
 * 
 * @returns {array}
 * [{
    match: '...',
    matchAtIndex: 0,
    capturedGroups: [ '...', '...' ]
  }]     
 */
function regexMatch(input, expression, flags = "g") {
  let regex = expression instanceof RegExp ? expression : new RegExp(expression, flags)
  let matches = input.matchAll(regex)
  matches = [...matches]
  return matches.map(item => {
    return {
      match: item[0],
      matchAtIndex: item.index,
      capturedGroups: item.length > 1 ? item.slice(1) : undefined
    }
  })
}

let input = "key1:value1, key2:value2 "
let regex = /(\w+):(\w+)/g

let matches = regexMatch(input, regex)

console.log(matches)


0

SADECE KULLANIM RegExp. $ 1 ... $ n inci grup örn .:

1. grup RegExp $ 1 maç için

  1. 2. grubu eşleştirmek için RegExp. 2 $

regex likey'de 3 grup kullanırsanız (string.match (regex) sonrasında not kullanın)

RegExp. 1 $ RegExp. 2 $ RegExp. 3 $

 var str = "The rain in ${india} stays safe"; 
  var res = str.match(/\${(.*?)\}/ig);
  //i used only one group in above example so RegExp.$1
console.log(RegExp.$1)

//easiest way is use RegExp.$1 1st group in regex and 2nd grounp like
 //RegExp.$2 if exist use after match

var regex=/\${(.*?)\}/ig;
var str = "The rain in ${SPAIN} stays ${mainly} in the plain"; 
  var res = str.match(regex);
for (const match of res) {
  var res = match.match(regex);
  console.log(match);
  console.log(RegExp.$1)
 
}

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.