นิพจน์ปกติเพื่อรับสตริงระหว่างวงเล็บใน Javascript


177

ฉันพยายามเขียนนิพจน์ทั่วไปซึ่งส่งคืนสตริงซึ่งอยู่ระหว่างวงเล็บ ตัวอย่างเช่นฉันต้องการรับสตริงที่อยู่ระหว่างสตริง "(" และ ")"

I expect five hundred dollars ($500).

จะกลับมา

$500

พบนิพจน์ปกติเพื่อรับสตริงระหว่างสองสตริงใน Javascript

แต่ฉันใหม่กับ regex ฉันไม่รู้วิธีใช้ '(', ')' ใน regexp



คุณสามารถใช้วิธีแก้ปัญหาของ go-oleg ด้านล่างปรับเปลี่ยนเล็กน้อยเพื่อทดสอบสำหรับเครื่องหมายดอลลาร์:var regExp = /\(\$([^)]+)\)/;
วันเดย์

คำตอบ:


460

คุณต้องสร้างชุดของ\วงเล็บ(พร้อม) วงเล็บ (ที่ตรงกับวงเล็บ) และกลุ่มของวงเล็บปกติที่สร้างกลุ่มจับภาพของคุณ:

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

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

ทำให้พังถล่ม:

  • \( : จับคู่วงเล็บเปิด
  • ( : เริ่มจับภาพกลุ่ม
  • [^)]+: จับคู่หนึ่งรายการที่ไม่ใช่ )อักขระที่ตัว
  • ) : สิ้นสุดการจับภาพกลุ่ม
  • \) : วงเล็บปิดที่ตรงกัน

นี่คือคำอธิบายภาพเกี่ยวกับRegExplained


12
+1 ดีทำงานได้ดี ฉันต้องการเพิ่มคุณเพื่อเพิ่มtinyurl.com/mog7lr3นี้ในคำอธิบายแบบภาพของคุณ
Praveen

5
@ user1671639: อัปเดต ขอบคุณสำหรับลิงค์!
go-oleg

5
วิธีนี้ใช้ไม่ได้หากมีวงเล็บอยู่ในวงเล็บที่คุณต้องการจับ เช่น: "ฉันคาดหวังห้าร้อยดอลลาร์ ($ 500 (แต่ฉันรู้ว่าฉันจะไม่เห็นเงินนั้นอีก))"
JayB

1
regex นี้ทำงานได้ก็ต่อเมื่อจับคู่หนึ่งอินสแตนซ์ต่อการต่อย การใช้/gค่าสถานะโกลบอลจะไม่ทำงานอย่างที่คาดไว้
silkAdmin

2
อะไรคือทางออกถ้าคุณมีหลายสตริงในวงเล็บดังนี้: "ฉันคาดหวัง (ห้า) ร้อยดอลลาร์ ($ 500)" สมมุติว่าฉันต้องการอาร์เรย์ของสตริงพิเศษเหล่านั้น
Mohamad Al Asmar

33

ลองการจัดการสตริง:

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]);
}

หรือ regex ( ซึ่งค่อนข้างช้าเมื่อเทียบกับด้านบน )

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
ทำงานที่ jsperf วันนี้ใน Chrome 59.0.3071, regex เร็วขึ้น 8%
Alex McMillan

9

รังเพลิงคำตอบ Mr_Green ของสไตล์การเขียนโปรแกรมการทำงานที่จะหลีกเลี่ยงการใช้ตัวแปรทั่วโลกชั่วคราว

var matches = string2.split('[')
  .filter(function(v){ return v.indexOf(']') > -1})
  .map( function(value) { 
    return value.split(']')[0]
  })

สิ่งที่ฉันกำลังมองหา stackoverflow.com/questions/49614116/…
wobsoriano


5

สำหรับตัวเลขหลังสัญลักษณ์สกุลเงิน: \(.+\s*\d+\s*\)ควรใช้งานได้

หรือ\(.+\)อะไรก็ได้ในวงเล็บ


2
สิ่งนี้จะใช้ได้กับข้อความตัวอย่างอย่างไรก็ตามหากข้อความอื่น)ปรากฏในภายหลังในสตริงเช่นI expect five hundred dollars ($500). (but I'm going to pay).ความโลภของ+ภาพจะจับภาพได้มากขึ้น
Ro Yo Mi Mi

@Denomales คุณจะให้มันจับอินสแตนซ์ของสตริงเหล่านั้นทั้งสองอย่างไร โดยหลักการแล้วฉันกำลังทำสิ่งที่คล้ายกัน แต่ฉันอยากจะมี: ($500)และ(but I'm going to pay) จับคู่ แต่ในการแข่งขันที่แยกกันสองรายการแทนที่จะเป็นรายการที่จับคู่เดียว ขอบคุณล่วงหน้า!
Tom Bird

(. +) ทำงานตามความต้องการของฉัน จำเป็นต้องรวบรวมเนื้อหาเช่น "Dunhill (ขวด / แพ็คเก็ต / หม้อ / ยิง)" และส่งคืนเฉพาะ "Dunhill"
GentleGiant

5

ในการจับคู่สตริงย่อยในวงเล็บไม่รวมวงเล็บภายในใด ๆ ที่คุณอาจใช้

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

แบบแผน ดูสาธิต regex

ใน JavaScript ให้ใช้เหมือนกัน

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

รายละเอียดรูปแบบ

หากต้องการจับคู่ทั้งหมดให้คว้าค่ากลุ่ม 0 หากคุณต้องการข้อความที่อยู่ในวงเล็บให้จับค่ากลุ่ม 1

การสาธิตโค้ด JavaScript ที่ทันสมัยที่สุด (โดยใช้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
});

การสาธิตโค้ด JavaScript ดั้งเดิม (สอดคล้องกับ ES5):


regex นี้ยอดเยี่ยมเพราะจับเฉพาะ()เนื้อหาและคู่ของพวกเขาแม้ว่าจะอยู่เคียงข้าง()()กัน
limitlessloop

1
@limitlessloop เนื่องจากนี่เป็นคำตอบที่เป็นประโยชน์ฉันจึงได้เพิ่มการmatchAllสาธิตโค้ด JavaScript ใหม่
Wiktor Stribiżew


2

ทางเลือก:

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

มันเป็นไปได้ที่จะเปลี่ยนวงเล็บด้วยวงเล็บเหลี่ยมหรือหยิกถ้าคุณต้องการ


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

จะจับคู่หมายเลขแรกที่เริ่มต้นด้วย $ และตามด้วย ')' ')' จะไม่เข้าร่วมการแข่งขัน รหัสแจ้งเตือนด้วยการจับคู่แรก

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]);
}

รหัสนี้แจ้งเตือนด้วยการแข่งขันทั้งหมด

อ้างอิง:

ค้นหา "? = n" http://www.w3schools.com/jsref/jsref_obj_regexp.asp

ค้นหา "x (? = y)" https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.