Regex để lấy chuỗi giữa các dấu ngoặc nhọn


115

Thật không may, mặc dù đã cố gắng học regex ít nhất một lần một năm trong nhiều năm tôi có thể nhớ được, nhưng tôi luôn quên vì tôi sử dụng chúng không thường xuyên. Năm nay, giải pháp năm mới của tôi là không thử học lại regex - Vì vậy, năm nay để cứu tôi khỏi nước mắt, tôi sẽ đưa nó cho Stack Overflow . (Bản hòa âm giáng sinh cuối cùng).

Tôi muốn chuyển vào một chuỗi ở định dạng này {getThis}và được trả về chuỗi getThis. Có ai có thể hỗ trợ trong việc giúp tôi giữ vững quyết tâm của năm mới không?


Các câu hỏi liên quan về Stack Overflow:


5
Câu hỏi này đã được thêm vào Câu hỏi Thường Gặp về Cụm từ Thông dụng Stack Overflow , trong "Advanced Regex-Fu".
aliteralmind

@Kobi: Câu hỏi thường gặp là một wiki. Bất kỳ ai cũng có thể chỉnh sửa nó. Vì vậy, hãy chỉnh sửa nó.
aliteralmind

Câu trả lời:


44

Nếu chuỗi của bạn luôn có định dạng đó, thì regex quá mức cần thiết:

>>> var g='{getThis}';
>>> g.substring(1,g.length-1)
"getThis"

substring(1có nghĩa là bắt đầu một ký tự trong (ngay sau ký tự đầu tiên {) và ,g.length-1)có nghĩa là lấy các ký tự cho đến khi (nhưng không bao gồm) ký tự ở độ dài chuỗi trừ đi một. Điều này hoạt động vì vị trí dựa trên 0, tức g.length-1là vị trí cuối cùng.

Đối với độc giả khác so với các poster ban đầu: Nếu nó trở thành một regex, sử dụng /{([^}]*)}/nếu bạn muốn cho phép chuỗi rỗng, hoặc /{([^}]+)}/nếu bạn muốn chỉ phù hợp khi có ít nhất một ký tự giữa dấu ngoặc nhọn. Phá vỡ:

  • /: bắt đầu mẫu regex
    • {: một dấu ngoặc nhọn theo nghĩa đen
      • (: bắt đầu chụp
        • [: bắt đầu xác định một lớp ký tự để nắm bắt
          • ^}: "bất cứ điều gì khác ngoài }"
        • ]: OK, đó là định nghĩa của cả lớp chúng ta
        • *: bất kỳ số ký tự nào phù hợp với lớp mà chúng tôi vừa xác định
      • ): chụp xong
    • }: một dấu ngoặc nhọn theo nghĩa đen phải ngay lập tức theo sau những gì chúng ta đã chụp
  • /: kết thúc mô hình regex

7
Chuỗi con là một trong những thứ thay đổi dựa trên ngôn ngữ bạn làm việc. Javascript lấy chỉ mục để dừng lại, PHP lấy độ dài của kết quả cuối cùng mong muốn (trừ khi nó âm, trong trường hợp đó, nó cần số ký tự để xóa) , C # lại khác ... hay và khó hiểu.
jvenema

2
... và Python chỉ có tính năng cắt, IMO nào tốt hơn bất cứ thứ gì khác: p.
Grant Paul

27
Ngọt ngào, nhưng không chắc đó là một biểu thức chính quy. Có lẽ anh đã yêu cầu regex, và tôi đến đây cho câu trả lời tương tự .. buồn bã câu trả lời không có gì để làm với các câu hỏi ..
baash05

5
@ baash05, nếu bạn đọc toàn bộ câu hỏi, OP thậm chí còn không muốn học regex, vì vậy tôi không nghĩ rằng đó là bài tập học thuật mà bạn dường như đang đề xuất.
Kev

2
Tôi muốn làm -1 vì câu hỏi đang yêu cầu regex , tôi đang tìm kiếm regex , nhưng câu trả lời được chấp nhận là hoàn toàn vô dụng đối với tôi (trong khi bản thân câu hỏi có vẻ rất hứa hẹn). Sau khi đọc nhận xét đầu tiên, tôi phải thừa nhận rằng nếu tôi trả lời câu hỏi này trước tiên, tôi có thể đã trả lời theo cùng một cách / tương tự ... Vì vậy, cuối cùng, +1.
shadyyx

250

Thử

/{(.*?)}/

Điều đó có nghĩa là, hãy so khớp bất kỳ ký tự nào giữa {và}, nhưng đừng tham lam - hãy so khớp chuỗi ngắn nhất kết thúc bằng} (dấu? Stop * là tham lam). Dấu ngoặc đơn cho phép bạn trích xuất phần phù hợp.

Một cách khác sẽ là

/{([^}]*)}/

Điều này khớp với bất kỳ ký tự nào ngoại trừ a} char (một cách khác để không tham lam)


điều này thật tuyệt vời, nhưng liệu có thể so khớp bất kỳ thứ gì giữa một số biến các tổ hợp dấu ngoặc nhọn không? Vd: "{this should be match} this shouldnt {this kinda should again} và như vậy {on}"? Tôi muốn truy xuất giá trị không nằm trong dấu ngoặc nhọn. Ngoài ra: dấu ngoặc nhọn sẽ không được sử dụng trong câu và không có sự xếp chồng (điều này sẽ không bao giờ xảy ra: "{some {text}}"). Bất cứ ai một ý tưởng làm thế nào để làm điều đó :)? Cảm ơn! (ps: ủng hộ giải pháp này)
Igor

4
Nó không nắm bắt mọi thứ giữa các dấu ngoặc nhọn, nó nắm bắt mọi thứ giữa các dấu ngoặc nhọn VÀ chính các dấu ngoặc nhọn. Bạn sẽ làm thế nào về việc CHỈ nắm bắt những gì bên trong dấu ngoặc nhọn?
Thực tế-Torrent

1
Tôi thích nó là bạn không cần phải thoát khỏi các dấu ngoặc nhọn ở đây vì trình phân tích cú pháp regex dường như nhận ra rằng chúng không phải là một bộ định lượng ... tốt, tôi đang làm điều này trong python, nhưng tôi cho rằng các regex của javascript hoạt động như vậy quá
drevicko

3
Thêm một gvào cuối làm cho nó trở thành một tìm kiếm toàn cầu. Xem một ví dụ làm việc
Benjamin

1
@ Reality-Torrent, tôi cũng thấy rằng nó chiếm được dấu ngoặc nhọn nếu tôi chỉ định tùy chọn g để nhận tất cả các kết quả phù hợp. Hóa ra tôi nên sử dụng Regex.exec trong một vòng lặp thay vì string.match trong Javascript để có cả cờ g và cho phép nhóm nắm bắt. Xem developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Frank

150
/\{([^}]+)\}/

/        - delimiter
\{       - opening literal brace escaped because it is a special character used for quantifiers eg {2,3}
(        - start capturing
[^}]     - character class consisting of
    ^    - not
    }    - a closing brace (no escaping necessary because special characters in a character class are different)
+        - one or more of the character class
)        - end capturing
\}       - the closing literal brace
/        - delimiter

@meouw sa = s.split ("/ \ {([^}] +) \} /"); đưa ra một lỗi biên dịch. lặp lại bất hợp pháp, ký tự thoát không hợp lệ.
likejudo

@Anil có vẻ như bạn đang sử dụng một chuỗi làm đối số tách thay vì một biểu thức chính quy. Bạn đang cố làm gì vậy?
meouw 26/12/12

30

Thử cái này:

/[^{\}]+(?=})/g

Ví dụ

Welcome to RegExr v2.1 by #{gskinner.com},  #{ssd.sd} hosted by Media Temple!

sẽ trở lại gskinner.com, ssd.sd.


1
Tuyệt vời, bạn có thể giải thích tại sao bạn sử dụng \}trong khối đầu tiên không?
Uzair Ali

1
Tốt, nhưng điều đó sẽ phù hợp với bất kỳ nhóm nào kết thúc bằng }, ngay cả khi nó không bắt đầu bằng {.
Ahmad Ibrahim

1
Đây là câu trả lời đúng duy nhất thực sự hoạt động.
pldg

Giải thích: Trong khi [^ \ {\}] + sẽ khớp với bất kỳ thứ gì không phải là dấu ngoặc nhọn, thì khẳng định lookahead (? =}) Sẽ đảm bảo chỉ chuyển các phần trước dấu ngoặc nhọn. Với / ... / g, chúng tôi nhận được tất cả các lần xuất hiện, không chỉ lần đầu tiên.
0 -_- 0

19

Đây là một giải pháp đơn giản bằng cách sử dụng javascript thay thế

var st = '{getThis}';

st = st.replace(/\{|\}/gi,''); // "getThis"

Như câu trả lời được chấp nhận ở trên chỉ ra rằng vấn đề ban đầu có thể dễ dàng giải quyết bằng chuỗi con, nhưng sử dụng thay thế có thể giải quyết các trường hợp sử dụng phức tạp hơn

Nếu bạn có một chuỗi như "randomstring999 [tên trường]", bạn sử dụng một mẫu hơi khác để lấy tên trường

var nameAttr = "randomstring999[fieldname]";

var justName = nameAttr.replace(/.*\[|\]/gi,''); // "fieldname"

15

Cái này hoạt động trong Textmate và nó khớp với mọi thứ trong một tệp CSS giữa các dấu ngoặc nhọn.

\{(\s*?.*?)*?\}

selector {. . matches here including white space. . .}

Nếu bạn muốn tiếp tục có thể trả lại nội dung, hãy gói tất cả nội dung đó trong một tập hợp các dấu ngoặc đơn như sau:

\{((\s*?.*?)*?)\}

và bạn có thể truy cập nội dung qua $ 1.

Điều này cũng hoạt động cho các hàm, nhưng tôi chưa thử nghiệm nó với các dấu ngoặc nhọn lồng nhau.


14

Bạn muốn sử dụng regex lookahead và lookbehind. Điều này sẽ chỉ cung cấp cho bạn những gì bên trong dấu ngoặc nhọn:

(?<=\{)(.*?)(?=\})

Phải có một dấu gạch chéo ngược thoát khỏi dấu ngoặc nhọn ở trên. Họ đã bị loại bỏ trong bài nộp của tôi.
Robert Cesaric

1
Cảm ơn, điều này đã giúp tôi ngày hôm nay.
ProfessionalAmateur

bất kỳ nhược điểm của phương pháp này?
Somatik

5
@ Somatik — vâng, cái nhìn tiêu cực và phía sau không được hỗ trợ trong ECMAScript.
RobG

Lưu ý: Ví dụ này hoạt động trong Java. Trả về tất cả các giá trị trong tất cả các dấu ngoặc nhọn.
ghép kênh

13

Thử cái này

let path = "/{id}/{name}/{age}";
const paramsPattern = /[^{\}]+(?=})/g;
let extractParams = path.match(paramsPattern);
console.log("extractParams", extractParams) // prints all the names between {} = ["id", "name", "age"]

1
Chính xác những gì tôi muốn :) này sẽ trả lại kết quả mà không cần niềng răng, các giải pháp khác trở lại với nó
Al-Mothafar

Tuyệt vời, câu trả lời hay nhất ở đây.
michal.jakubeczy

4

Regex để nhận các mảng chuỗi có dấu ngoặc nhọn bao quanh xảy ra trong chuỗi, thay vì chỉ tìm lần xuất hiện đầu tiên.

 /\{([^}]+)\}/gm 

4

tôi đã xem xét các câu trả lời khác, và một logic quan trọng dường như bị thiếu trong chúng. tức là, chọn mọi thứ giữa hai dấu ngoặc nhọn CHỨNG MINH, nhưng KHÔNG phải dấu ngoặc

vì vậy, đây là câu trả lời của tôi

\{([^{}]+)\}

3
var re = /{(.*)}/;
var m = "{helloworld}".match(re);
if (m != null)
    console.log(m[0].replace(re, '$1'));

Đơn giản hơn .replace(/.*{(.*)}.*/, '$1')không may trả về toàn bộ chuỗi nếu regex không khớp. Đoạn mã trên có thể dễ dàng phát hiện một kết quả phù hợp hơn.



2

Bạn có thể sử dụng đệ quy regex này để so khớp mọi phần giữa, thậm chí là một phần khác {}(như văn bản JSON):

\{([^()]|())*\}

Đẹp, nhưng điều này chỉ nắm bắt được nội dung bên trong dấu ngoặc nhọn lồng nhau
Dominic

không chụp nếu nội dung chứa ()
Mert Mertce

1

Ngay cả điều này cũng giúp tôi trong khi cố gắng giải quyết vấn đề của ai đó,

Tách nội dung bên trong dấu ngoặc nhọn ( {}) có mẫu như, {'day': 1, 'count': 100} ,.

Ví dụ:

#include <iostream> 
#include <regex> 
#include<string> 
using namespace std; 

int main() 
{ 
    //string to be searched
    string s = "{'day': 1, 'count': 100}, {'day': 2, 'count': 100}";

    // regex expression for pattern to be searched 
    regex e ("\\{[a-z':, 0-9]+\\}");
    regex_token_iterator<string::iterator> rend;

    regex_token_iterator<string::iterator> a ( s.begin(), s.end(), e );
    while (a!=rend) cout << " [" << *a++ << "]";
    cout << endl;

    return 0; 
}

Đầu ra:

[{'day': 1, 'count': 100}] [{'day': 2, 'count': 100}]
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.