Làm thế nào để bạn truy cập các nhóm phù hợp trong một biểu thức chính quy JavaScript?


1368

Tôi muốn khớp một phần của chuỗi bằng biểu thức chính quy và sau đó truy cập chuỗi con được ngoặc đơn đó:

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 (!!!)

Tôi đang làm gì sai?


Tôi đã phát hiện ra rằng không có gì sai với mã biểu thức chính quy ở trên: chuỗi thực tế mà tôi đang kiểm tra là:

"date format_%A"

Báo cáo rằng "% A" không được xác định có vẻ là một hành vi rất lạ, nhưng nó không liên quan trực tiếp đến câu hỏi này, vì vậy tôi đã mở một câu hỏi mới, Tại sao một chuỗi con phù hợp lại trả về "không xác định" trong JavaScript? .


Vấn đề là console.loglấy các tham số của nó như một printfcâu lệnh và vì chuỗi tôi đang ghi ( "%A") có một giá trị đặc biệt, nó đã cố gắng tìm giá trị của tham số tiếp theo.

Câu trả lời:


1674

Bạn có thể truy cập các nhóm chụp như thế này:

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

Và nếu có nhiều trận đấu, bạn có thể lặp lại chúng:

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

Chỉnh sửa: 2019-09-10

Như bạn có thể thấy cách lặp lại qua nhiều trận đấu không trực quan lắm. Điều này dẫn đến đề xuất của String.prototype.matchAllphương pháp. Phương pháp mới này dự kiến ​​sẽ xuất xưởng trong đặc tả ECMAScript 2020 . Nó cung cấp cho chúng tôi một API sạch và giải quyết nhiều vấn đề. Nó đã được bắt đầu đổ bộ lên các trình duyệt và công cụ JS chính như Chrome 73+ / Node 12+ và Firefox 67+.

Phương thức trả về một iterator và được sử dụng như sau:

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

Khi nó trả về một trình vòng lặp, chúng ta có thể nói nó lười biếng, điều này rất hữu ích khi xử lý một số lượng lớn các nhóm bắt hoặc các chuỗi rất lớn. Nhưng nếu bạn cần, kết quả có thể dễ dàng chuyển thành Mảng bằng cách sử dụng cú pháp trải hoặc Array.fromphương thức:

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

Trong khi đó, trong khi đề xuất này được hỗ trợ rộng rãi hơn, bạn có thể sử dụng gói shim chính thức .

Ngoài ra, các hoạt động nội bộ của phương pháp là đơn giản. Việc thực hiện tương đương bằng cách sử dụng chức năng tạo sẽ như sau:

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

Một bản sao của biểu thức chính quy được tạo ra; điều này là để tránh các tác dụng phụ do sự đột biến của lastIndextài sản khi trải qua nhiều trận đấu.

Ngoài ra, chúng ta cần đảm bảo regrec có cờ toàn cầu để tránh vòng lặp vô hạn.

Tôi cũng rất vui khi thấy rằng ngay cả câu hỏi StackOverflow này đã được tham khảo trong các cuộc thảo luận về đề xuất .


114
+1 Xin lưu ý rằng trong ví dụ thứ hai, bạn nên sử dụng đối tượng RegExp (không chỉ "/ myregapi /"), vì nó giữ giá trị Last Index trong đối tượng. Nếu không sử dụng đối tượng
Regapi,

7
@ianaz: Tôi không tin 'đây là sự thật? http://jsfiddle.net/weEg9/ dường như hoạt động trên Chrome, ít nhất.
spinarrow

16
Tại sao làm như trên thay vì : var match = myString.match(myRegexp); // alert(match[1])?
John ALLen 30/12/13

29
Không cần "RegExp mới" rõ ràng, tuy nhiên vòng lặp vô hạn sẽ xảy ra trừ khi / g được chỉ định
George C

4
Một cách khác để không chạy vào vòng lặp vô hạn là chuỗi cập nhật explicetly, ví dụ:string = string.substring(match.index + match[0].length)
Olga

186

Đây là một phương pháp bạn có thể sử dụng để có được nhóm bắt thứ n cho mỗi trận đấu:

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
Đây là một câu trả lời vượt trội hơn nhiều so với những người khác vì nó hiển thị chính xác lặp lại trên tất cả các trận đấu thay vì chỉ nhận được một.
Rob Evans

13
mnn nói đúng Điều này sẽ tạo ra một vòng lặp vô hạn nếu không có cờ 'g'. Hãy thật cẩn thận với chức năng này.
Druska

4
Tôi đã cải thiện điều này để làm cho nó tương tự như re.findall () của python. Nó nhóm tất cả các trận đấu thành một mảng các mảng. Nó cũng sửa vấn đề vòng lặp vô hạn sửa đổi toàn cầu. jsfiddle.net/ravishi/MbwpV
ravishi

5
@MichaelMikowski bây giờ bạn vừa ẩn vòng lặp vô hạn của mình, nhưng mã của bạn sẽ chạy chậm. Tôi tranh luận rằng tốt hơn hết là nên phá mã theo cách xấu để bạn nắm bắt nó trong quá trình phát triển. Đặt một số bs lặp lại tối đa đột nhập là cẩu thả. Ẩn các vấn đề thay vì khắc phục nguyên nhân gốc rễ của họ không phải là câu trả lời.
wallacer

4
@MichaelMikowski không có ý nghĩa chậm hơn khi bạn không đạt giới hạn thực hiện. Khi bạn là, nó rõ ràng chậm hơn nhiều. Tôi không nói rằng mã của bạn không hoạt động, tôi đang nói rằng trong thực tế tôi nghĩ rằng nó sẽ gây hại nhiều hơn là tốt. Những người làm việc trong môi trường dev sẽ thấy mã hoạt động tốt trong điều kiện không tải mặc dù thực hiện 10.000 lần thực thi không cần thiết của một số đoạn mã. Sau đó, họ sẽ đẩy nó ra môi trường sản xuất và tự hỏi tại sao ứng dụng của họ lại bị tải. Theo kinh nghiệm của tôi, sẽ tốt hơn nếu mọi thứ phá vỡ một cách rõ ràng và sớm hơn trong chu kỳ phát triển.
wallacer

58

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

Điều \bnày không hoàn toàn giống nhau. (Nó hoạt động trên --format_foo/, nhưng không hoạt động format_a_b) Nhưng tôi muốn hiển thị một thay thế cho biểu hiện của bạn, điều này là tốt. Tất nhiên, matchcuộc gọi là điều quan trọng.


2
Nó hoàn toàn ngược lại. '\ b' phân định các từ. từ = '\ w' = [a-zA-Z0-9_]. "format_a_b" là một từ.
BF

1
@BFHestest, tôi đã thêm "không hoạt động format_a_b" như sau 6 năm trước, và tôi không nhớ những gì tôi muốn nói ở đó ... :-) Tôi cho rằng nó có nghĩa là "không hoạt động để achỉ chụp ", I E. phần chữ cái đầu tiên sau format_.
PhiLho

1
Tôi muốn nói rằng \ b (- format_foo /} \ b không trả về "--format_foo /" vì "-" và "/" không có ký tự \. Nhưng \ b (format_a_b) \ b không trả về "format_a_b ". Phải không? Tôi đề cập đến tuyên bố văn bản của bạn trong ngoặc tròn. (Không bỏ phiếu!)
BF

31

Liên quan đến các ví dụ về dấu ngoặc đơn nhiều kết hợp ở trên, tôi đã tìm kiếm một câu trả lời ở đây sau khi không nhận được những gì tôi muốn từ:

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

Sau khi xem các hàm gọi hơi phức tạp với while và .push () ở trên, tôi nhận ra rằng vấn đề có thể được giải quyết rất thanh lịch với mystring.replace () (thay thế KHÔNG phải là vấn đề, và thậm chí còn không được thực hiện , tùy chọn gọi hàm đệ quy SẠCH, tích hợp cho tham số thứ hai là!):

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

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

Sau này, tôi không nghĩ mình sẽ sử dụng .match () cho hầu hết mọi thứ nữa.


26

Cuối cùng nhưng không kém phần quan trọng, tôi đã tìm thấy một dòng mã hoạt động tốt với tôi (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);

Điều này sẽ trở lại:

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

1
BÙM! Đó là các giải pháp thanh lịch nhất ở đây. Tôi thấy điều này tốt hơn so với replacecách tiếp cận đầy đủ của Alexz bởi vì cách này ít nhìn về phía trước và thanh lịch hơn cho nhiều kết quả. Làm tốt công việc này, Sebastien H.
Cody

Điều này hoạt động tốt đến mức nó chắc chắn sẽ đi vào dụng cụ của tôi :)
Cody

1
@Cody haha ​​cảm ơn người đàn ông!
Sebastien H.

19

Thuật ngữ được sử dụng trong câu trả lời này:

  • Khớp cho biết kết quả của việc chạy mẫu RegEx của bạn đối với chuỗi của bạn như vậy : someString.match(regexPattern).
  • Các mẫu trùng khớp cho biết tất cả các phần khớp của chuỗi đầu vào, tất cả nằm trong mảng khớp . Đây là tất cả các phiên bản của mẫu của bạn bên trong chuỗi đầu vào.
  • Các nhóm phù hợp chỉ ra tất cả các nhóm cần bắt, được xác định trong mẫu RegEx. (Các mẫu bên trong dấu ngoặc đơn, như vậy : /format_(.*?)/g, nơi (.*?)sẽ là một nhóm phù hợp.) Chúng nằm trong các mẫu phù hợp .

Sự miêu tả

Để có quyền truy cập vào các nhóm phù hợp , trong mỗi mẫu phù hợp , bạn cần một hàm hoặc một cái gì đó tương tự như lặp lại trong trận đấu . Có một số cách bạn có thể làm điều này, như nhiều câu trả lời khác cho thấy. Hầu hết các câu trả lời khác sử dụng vòng lặp while để lặp lại tất cả các mẫu phù hợp , nhưng tôi nghĩ tất cả chúng ta đều biết những nguy cơ tiềm ẩn với cách tiếp cận đó. Nó là cần thiết để phù hợp với một new RegExp()thay vì chỉ mẫu, mà chỉ được đề cập trong một bình luận. Điều này là do .exec()phương thức này hoạt động tương tự như hàm tạo - nó dừng mỗi khi có kết quả khớp , nhưng giữ cho nó .lastIndextiếp tục từ đó trong .exec()cuộc gọi tiếp theo .

Mã ví dụ

Dưới đây là một ví dụ về hàm searchStringtrả về một Arraytrong tất cả các mẫu phù hợp , trong đó mỗi mẫu matchlà một Arrayvới tất cả các nhóm được khớp . Thay vì sử dụng một vòng lặp while, tôi đã cung cấp các ví dụ bằng cách sử dụng cả Array.prototype.map()chức năng cũng như cách thức hiệu quả hơn - sử dụng đơn giản for-loop.

Phiên bản súc tích (ít mã hơn, nhiều cú pháp hơn)

Đây là ít hiệu suất hơn vì về cơ bản họ thực hiện một forEach-loop thay vì for-loop nhanh hơn .

// 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

Phiên bản biểu diễn (nhiều mã hơn, ít cú pháp hơn)

// 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

Tôi vẫn chưa so sánh các lựa chọn thay thế này với các câu trả lời trước đây được đề cập trong các câu trả lời khác, nhưng tôi nghi ngờ phương pháp này ít hiệu quả hơn và ít an toàn hơn các phương pháp khác.


19

String#matchAll (xem đề xuất Dự thảo giai đoạn 3 / ngày 7 tháng 12 năm 2018 ), đơn giản hóa việc truy cập cho tất cả các nhóm trong đối tượng khớp (lưu ý rằng Nhóm 0 là toàn bộ trận đấu, trong khi các nhóm tiếp theo tương ứng với các nhóm bắt giữ trong mẫu):

Với tính matchAllkhả dụng, bạn có thể tránh whilevòng lặp và execvới /g... Thay vào đó, bằng cách sử dụng matchAll, bạn lấy lại một trình vòng lặp mà bạn có thể sử dụng với tiện ích for...of, trải rộng mảng hoặc thuận tiện hơnArray.from() cấu trúc

Phương pháp này mang lại một đầu ra tương tự như Regex.Matches trong C #, re.finditertrong Python, preg_match_alltrong PHP.

Xem bản demo JS (được thử nghiệm trong Google Chrome 73.0.3683.67 (bản dựng chính thức), beta (64-bit)):

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

Các console.log([...matches])chương trình

nhập mô tả hình ảnh ở đây

Bạn cũng có thể nhận được giá trị khớp hoặc giá trị nhóm cụ thể bằng cách sử dụng

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" ]

LƯU Ý : Xem chi tiết tương thích trình duyệt .


Ví dụ hoàn hảo cho các cặp giá trị chính. Súc tích và dễ đọc, rất đơn giản để sử dụng. Ngoài ra, xử lý lỗi tốt hơn, chênh lệch sẽ trả về một mảng trống thay vì null, do đó, không còn 'lỗi, không có "độ dài" thuộc tính của null'
Jarrod McGuire

17

Cú pháp của bạn có lẽ không phải là tốt nhất để giữ. FF / Gecko định nghĩa RegExp là một phần mở rộng của Hàm.
(FF2 đã đi xa như typeof(/pattern/) == 'function')

Có vẻ như điều này là dành riêng cho FF - IE, Opera và Chrome, tất cả đều có ngoại lệ cho nó.

Thay vào đó, sử dụng một trong hai phương pháp được đề cập trước đây bởi người khác: RegExp#exechoặc String#match.
Họ cung cấp kết quả tương tự:

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

Không cần phải gọi execphương thức! Bạn có thể sử dụng phương thức "khớp" trực tiếp trên chuỗi. Chỉ cần đừng quên dấu ngoặc đơ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...

Vị trí 0 có một chuỗi với tất cả các kết quả. Vị trí 1 có trận đấu đầu tiên được biểu thị bằng dấu ngoặc đơn và vị trí 2 có trận đấu thứ hai được phân lập trong ngoặc đơn của bạn. Dấu ngoặc đơn lồng nhau là khó khăn, vì vậy hãy cẩn thận!


4
Nếu không có cờ toàn cầu, điều này sẽ trả về tất cả các trận đấu, với nó, bạn sẽ chỉ nhận được một trận đấu lớn vì vậy hãy coi chừng điều đó.
Shadymilkman01

8

Một lớp lót chỉ thực tế nếu bạn có một cặp dấu ngoặc đơn:

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

4
Tại sao khôngwhile (match = myRegex.exec(myStr)) matches.push(match[1])
willlma

7

Sử dụng mã của bạn:

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

Chỉnh sửa: Safari 3, nếu nó quan trọng.


7

Với es2018 bây giờ bạn có thể String.match()với các nhóm được đặt tên, làm cho biểu thức chính của bạn rõ ràng hơn về những gì nó đã cố gắng thực hiện.

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

và bạn sẽ nhận được một cái gì đó như

{giao thức: "https", tên máy chủ: "stackoverflow.com", tên đường dẫn: "question / 432493 / how-do-you-access-the-Match-Groups-in-a-javascript-normal-express", chuỗi truy vấn: " some = tham số "}


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

Mã của bạn hoạt động với tôi (FF3 trên Mac) ngay cả khi tôi đồng ý với PhiLo rằng regex có lẽ phải là:

/\bformat_(.*?)\b/

(Nhưng, tất nhiên, tôi không chắc lắm vì tôi không biết bối cảnh của regex.)


1
đó là một danh sách được phân tách bằng dấu cách để tôi nghĩ rằng nó sẽ ổn thôi. lạ là mã đó không hoạt động với tôi (FF3 Vista)
nickf

1
Vâng, thực sự kỳ lạ. Bạn đã tự mình thử nó trong bảng điều khiển Fireorms chưa? Từ một trang trống khác, ý tôi là.
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

Bạn không thực sự cần một vòng lặp rõ ràng để phân tích nhiều kết quả khớp - chuyển một hàm thay thế làm đối số thứ hai như được mô tả trong 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);

Các m0tham số đại diện cho chuỗi xuất hiện đầy đủ {0}, {1}vv m1đại diện cho nhóm phù hợp đầu tiên, tức là phần kèm theo trong ngoặc trong regex mà là 0cho trận đấu đầu tiên. Và positionlà chỉ mục bắt đầu trong chuỗi nơi tìm thấy nhóm phù hợp - không được sử dụng trong trường hợp này.


1

Chúng ta có thể truy cập nhóm phù hợp trong một biểu thức thông thường bằng cách sử dụng dấu gạch chéo ngược theo sau là số của nhóm phù hợp:

/([a-z])\1/

Trong mã \ 1 được đại diện khớp bởi nhóm đầu tiên ([az])


1

Giải pháp một dòng:

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

Vì vậy, bạn có thể sử dụng cách này (phải sử dụng / g):

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

kết quả:

[" format_abc"]

0

Nhận tất cả sự xuất hiện của nhóm

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

Tôi giống như bạn và mong muốn regex sẽ trả lại một Object như thế này:

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

sau đó cắt chức năng từ bên dưới

/**
 * @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

CHỈ SỬ DỤNG RegExp. $ 1 ... $ n nhóm thứ hai, vd:

1.Để phù hợp với nhóm 1 RegExp. $ 1

  1. Để phù hợp với nhóm thứ 2 RegExp. $ 2

nếu bạn sử dụng 3 nhóm trong regex likey (lưu ý sử dụng sau string.match (regex))

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.