Wyrażenie regularne, aby pobrać ciąg w nawiasach w JavaScript


177

Próbuję napisać wyrażenie regularne, które zwraca ciąg, który znajduje się w nawiasach. Na przykład: chcę uzyskać ciąg znajdujący się między ciągami „(” i „)”

I expect five hundred dollars ($500).

wróci

$500

Znaleziono wyrażenie regularne, aby pobrać ciąg między dwoma ciągami w JavaScript

Ale jestem nowy w regex. Nie wiem, jak użyć znaku „(”, „)” w wyrażeniu regularnym



możesz użyć rozwiązania go-olega poniżej, nieznacznie zmodyfikowanego, aby przetestować znak dolara:var regExp = /\(\$([^)]+)\)/;
Dom Day,

Odpowiedzi:


460

Musisz utworzyć zestaw \nawiasów ze zmianą znaczenia (z ) nawiasami (pasującymi do nawiasów) i grupę zwykłych nawiasów, które tworzą twoją grupę przechwytywania:

var regExp = /\(([^)]+)\)/;
var matches = regExp.exec("I expect five hundred dollars ($500).");

//matches[1] contains the value between the parentheses
console.log(matches[1]);

Awaria:

  • \( : dopasuj otwierający nawias
  • ( : rozpocznij przechwytywanie grupy
  • [^)]+: dopasuj jeden lub więcej )znaków niebędących znakami
  • ) : koniec grupy przechwytywania
  • \) : dopasuj nawiasy zamykające

Oto wizualne wyjaśnienie RegExplained


12
+1 Ładny, działał jak urok. Chciałbym Cię dodać, aby dodać ten tinyurl.com/mog7lr3 w Twoim, aby uzyskać wizualne wyjaśnienie.
Praveen

5
@ user1671639: Zaktualizowano. Dzięki za link!
go-oleg

5
To nie działa, jeśli w nawiasach są nawiasy, które chcesz przechwycić. Na przykład: „Oczekuję pięciuset dolarów (500 dolarów (ale wiem, że już nigdy nie zobaczę tych pieniędzy)”.
JayB

1
To wyrażenie regularne działa tylko wtedy, gdy pasuje do jednej instancji na żądło. Używanie /gflagi globalnej nie zadziała zgodnie z oczekiwaniami.
silkAdmin

2
jakie jest rozwiązanie, jeśli masz wiele ciągów w nawiasach, jak poniżej: „Oczekuję (pięć) stu dolarów (500 USD)”, powiedzmy, że chcę tablicę tych specjalnych ciągów.
Mohamad Al Asmar

33

Spróbuj manipulować ciągami:

var txt = "I expect five hundred dollars ($500). and new brackets ($600)";
var newTxt = txt.split('(');
for (var i = 1; i < newTxt.length; i++) {
    console.log(newTxt[i].split(')')[0]);
}

lub wyrażenie regularne ( co jest nieco powolne w porównaniu z powyższym )

var txt = "I expect five hundred dollars ($500). and new brackets ($600)";
var regExp = /\(([^)]+)\)/g;
var matches = txt.match(regExp);
for (var i = 0; i < matches.length; i++) {
    var str = matches[i];
    console.log(str.substring(1, str.length - 1));
}

7
Uruchomienie tego jsperfa dzisiaj w Chrome 59.0.3071 sprawiło, że wyrażenie regularne było szybsze o 8%
Alex McMillan,


8

Proste rozwiązanie

Uwaga : to rozwiązanie może być użyte do łańcuchów zawierających tylko pojedyncze znaki „(” i „)” w tym pytaniu.

("I expect five hundred dollars ($500).").match(/\((.*)\)/).pop();

Demo online (jsfiddle)


5

Tylko cyfry po znaku waluty: \(.+\s*\d+\s*\)powinno działać

Lub \(.+\)cokolwiek w nawiasach


2
To zadziała dla przykładowego tekstu, jednak jeśli inny )pojawi się później w ciągu, jak I expect five hundred dollars ($500). (but I'm going to pay).chciwość +, przechwyci znacznie więcej.
Ro Yo Mi,

@Denomales Więc jak byś przechwytywał oba wystąpienia tych ciągów. Idealnie byłoby, gdyby robiłam coś podobnego, ale chciałbym mieć: ($500)i (but I'm going to pay) być dopasowanym, ale w dwóch oddzielnych dopasowaniach, a nie być uważanym za jeden dopasowany element? Z góry dziękuję!
Tom Bird

(. +) działał na moje wymagania. Potrzebne do przechwytywania rzeczy takich jak „Dunhill (butelka / paczka / garnek / strzał)” i zwracania tylko „Dunhill”
GentleGiant

5

Aby dopasować podciąg wewnątrz nawiasów, z wyłączeniem wszelkich wewnętrznych nawiasów, których możesz użyć

\(([^()]*)\)

wzór. Zobacz na demo regex .

W JavaScript używaj tego jak

var rx = /\(([^()]*)\)/g;

Szczegóły wzoru

  • \(- (char
  • ([^()]*)- Grupa przechwytująca 1: zanegowana klasa znaków pasująca do 0 lub więcej znaków innych niż (i)
  • \)- )char.

Aby uzyskać całe dopasowanie, weź wartość z grupy 0, jeśli potrzebujesz tekstu w nawiasach, weź wartość z grupy 1.

Najbardziej aktualna wersja demonstracyjna kodu JavaScript (przy użyciu matchAll):

const strs = ["I expect five hundred dollars ($500).", "I expect.. :( five hundred dollars ($500)."];
const rx = /\(([^()]*)\)/g;
strs.forEach(x => {
  const matches = [...x.matchAll(rx)];
  console.log( Array.from(matches, m => m[0]) ); // All full match values
  console.log( Array.from(matches, m => m[1]) ); // All Group 1 values
});

Prezentacja starszego kodu JavaScript (zgodna z ES5):


To wyrażenie regularne jest świetne, ponieważ przechwytuje tylko pary ()i ich zawartość, nawet gdy są obok siebie ()().
nieograniczona

1
@limitlessloop Ponieważ wydaje się to pomocna odpowiedź, dodałem również nową matchAllwersję demonstracyjną kodu JavaScript.
Wiktor Stribiżew

3

let str = "Before brackets (Inside brackets) After brackets".replace(/.*\(|\).*/g, '');
console.log(str) // Inside brackets


2

Alternatywny:

var str = "I expect five hundred dollars ($500) ($1).";
str.match(/\(.*?\)/g).map(x => x.replace(/[()]/g, ""));
 (2) ["$500", "$1"]

W razie potrzeby można zastąpić nawiasy kwadratowe lub klamrowe


1
var str = "I expect five hundred dollars ($500) ($1).";
var rex = /\$\d+(?=\))/;
alert(rex.exec(str));

Dopasuje pierwszą liczbę zaczynającą się od znaku $ i zakończonej znakiem „)”. „)” nie będzie częścią dopasowania. Kod ostrzega przy pierwszym dopasowaniu.

var str = "I expect five hundred dollars ($500) ($1).";
var rex = /\$\d+(?=\))/g;
var matches = str.match(rex);
for (var i = 0; i < matches.length; i++)
{
    alert(matches[i]);
}

Ten kod ostrzega o wszystkich dopasowaniach.

Bibliografia:

wyszukaj „? = n” http://www.w3schools.com/jsref/jsref_obj_regexp.asp

wyszukaj „x (? = y)” https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.