중괄호 사이에 문자열을 가져 오는 정규식


115

불행히도, 내가 기억할 수있는 한 수년 동안 적어도 일년에 한 번 정규식을 배우려고 했음에도 불구하고 나는 그것을 자주 사용하지 않기 때문에 항상 잊어 버립니다. 올해 내 새해 결심은 정규식을 다시 배우지 않는 것입니다. 그래서 올해는 눈물에서 나를 구하기 위해 Stack Overflow에 줄 것 입니다. (마지막 크리스마스 리믹스).

이 형식의 문자열을 전달하고 문자열을 {getThis}반환하고 싶습니다 getThis. 새해 결심을 지키는 데 도움을 줄 사람이 있습니까?


Stack Overflow에 대한 관련 질문 :


5
이 질문은 "Advanced Regex-Fu"아래 의 Stack Overflow Regular Expression FAQ 에 추가되었습니다 .
aliteralmind

@Kobi : FAQ는 위키입니다. 누구나 편집 할 수 있습니다. 그래서 그것을 편집하십시오.
aliteralmind

답변:


44

문자열이 항상 해당 형식이면 정규식은 과잉입니다.

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

substring(1수단 (단지 첫번째 과거에 한 문자를 시작합니다 {)과 ,g.length-1)수단은 문자열 길이를 뺀 하나의 문자 (하지만 제외)까지 문자를 취할 수 있습니다. 이것은 위치가 0부터 시작하기 때문에 작동합니다 g.length-1. 즉 , 마지막 위치입니다.

원래 포스터가 아닌 독자의 경우 :이 경우 정규식 사용으로 /{([^}]*)}/당신이 빈 문자열을 허용 할 경우, 또는 /{([^}]+)}/중괄호 사이에 적어도 하나 개의 문자가있는 경우에만 일치합니다. 고장:

  • /: 정규식 패턴 시작
    • {: 리터럴 중괄호
      • (: 캡처 시작
        • [: 캡처 할 캐릭터 클래스 정의 시작
          • ^}: "다른 것 }"
        • ]: 좋습니다. 이것이 우리의 전체 클래스 정의입니다.
        • *: 방금 정의한 해당 클래스와 일치하는 문자 수
      • ): 캡처 완료
    • }: 리터럴 중괄호는 캡처 한 내용 바로 뒤에 와야합니다.
  • /: 정규식 패턴 종료

7
Substringing은 작업하는 언어에 따라 변경되는 것들 중 하나입니다. Javascript는 인덱스를 사용하고 PHP는 원하는 최종 결과의 길이를 사용합니다 (음수가 아닌 경우 제거 할 문자 수). , C #은 또 다릅니다 ... 좋고 혼란 스럽습니다.
jvenema

2
... 그리고 파이썬은 슬라이싱을 가지고 있습니다. IMO는 다른 어떤 것보다 낫습니다.
Grant Paul

27
달콤하지만 그것이 정규 표현식인지 확실하지 않습니다. 아마도 그는 정규식을 요구하고 있었는데 나는 같은 대답을 위해 여기에 왔습니다. 슬프게도 대답은 질문과 관련이 없습니다 ..
baash05

5
@ baash05, 전체 질문을 읽으면 OP는 정규식을 배우고 싶지 않았기 때문에 그것이 당신이 제안하는 학문적 운동이라고 생각하지 않습니다.
Kev 2011

2
내가 할 -1 질문이 요구되기 때문에 원하는 정규식 , 내가 검색 한 정규식 하지만 (문제는 매우 자체를 약속하는 듯하면서) 허용 대답은 나에게 완전히 쓸모가 없었습니다. 첫 번째 댓글을 읽은 후이 질문에 먼저 대답했다면 동일 / 유사한 방법으로 대답 할 수 있었음을 인정해야합니다. 결국에는 +1.
shadyyx

250

시험

/{(.*?)}/

즉, {와} 사이의 모든 문자와 일치하되 욕심 내지 마십시오.}로 끝나는 가장 짧은 문자열과 일치합니다 (?는 욕심을 멈 춥니 다.). 괄호를 사용하면 일치하는 부분을 추출 할 수 있습니다.

또 다른 방법은

/{([^}]*)}/

} 문자를 제외한 모든 문자와 일치합니다 (욕심을 내지 않는 또 다른 방법).


이것은 훌륭하지만 다양한 수의 중괄호 조합 사이에서 무엇이든 일치시킬 수 있습니까? 예 : "{이 일치해야 함} 이것이 안 돼요 {이것이 다시해야합니다} 그래서 {on}"? 중괄호 안에 있지 않은 값을 검색하고 싶습니다. 또한 : 중괄호는 문장에서 사용되지 않으며 스택이 없습니다 (이는 발생하지 않음 : "{some {text}}"). 누구든지 그것을하는 방법에 대한 아이디어 :)? 감사! (ps :이 솔루션에 찬성 투표)
Igor

4
중괄호 사이의 모든 것을 캡처하는 것이 아니라 중괄호와 중괄호 자체 사이의 모든 것을 캡처합니다. 중괄호 안에있는 것만 캡처하는 방법은 무엇입니까?
Reality-Torrent

1
정규식 파서가 수량자가 아니라는 것을 인식하는 것처럼 보이므로 여기에서 중괄호를 이스케이프 할 필요가 없다는 점이 마음에 듭니다 ... 음, 저는 파이썬에서이 작업을 수행하고 있지만 자바 스크립트 정규식이 그렇게 작동한다고 가정합니다 너무
drevicko

3
g끝에 추가하면 글로벌 검색이됩니다. 참조 작업 예
벤자민

1
@ Reality-Torrent, 모든 일치 항목을 가져 오기 위해 g 옵션을 지정하면 중괄호를 캡처 한 것도 보았습니다. Javascript에서 string.match 대신 루프에서 Regex.exec를 사용하여 g 플래그를 모두 갖고 캡처 그룹을 허용해야합니다. 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 ( "/ \ {([^}] +) \} /"); 컴파일 오류가 발생합니다. 잘못된 반복, 잘못된 이스케이프 문자.
likejudo 2012

@Anil 정규 표현식이 아닌 분할 인수로 문자열을 사용하는 것으로 보입니다. 무엇을하려고합니까?
meouw

30

이 시도:

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

예를 들면

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

반환합니다 gskinner.com, ssd.sd.


1
좋습니다 \}. 첫 번째 블록에서 사용하는 이유를 설명해 주 시겠습니까?
Uzair Ali

1
좋은 것입니다.하지만로 }시작하지 않더라도로 끝나는 모든 그룹과 일치합니다 {.
Ahmad Ibrahim

1
이것은 실제로 작동하는 유일한 정답입니다.
pldg

설명 : [^ \ {\}] +는 중괄호가 아닌 모든 항목과 일치하지만 미리보기 어설 션 (? =})은 중괄호 앞의 섹션 만 전달합니다. / ... / g를 사용하면 첫 번째 항목뿐만 아니라 모든 항목이 표시됩니다.
0 -_- 0

19

다음은 javascript replace를 사용하는 간단한 솔루션입니다.

var st = '{getThis}';

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

위의 대답에서 지적했듯이 원래 문제는 부분 문자열로 쉽게 해결되지만 replace를 사용하면 더 복잡한 사용 사례를 해결할 수 있습니다.

"randomstring999 [fieldname]"과 같은 문자열이있는 경우 약간 다른 패턴을 사용하여 fieldname을 가져옵니다.

var nameAttr = "randomstring999[fieldname]";

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

15

이것은 Textmate에서 작동하며 중괄호 사이에있는 CSS 파일의 모든 항목과 일치합니다.

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

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

콘텐츠를 추가로 반환하려면 다음과 같이 하나 이상의 괄호로 모두 래핑합니다.

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

$ 1를 통해 콘텐츠에 액세스 할 수 있습니다.

이것은 함수에서도 작동하지만 중첩 중괄호로 테스트하지 않았습니다.


14

regex lookahead 및 lookbehind를 사용하려고합니다. 이것은 중괄호 안에있는 것만 제공합니다.

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

위의 중괄호를 이스케이프하는 백 슬래시가 있어야합니다. 내 제출물에서 제거되었습니다.
Robert Cesaric 2010

1
감사합니다. 오늘 도움이되었습니다.
ProfessionalAmateur

이 방법의 단점은 무엇입니까?
Somatik

5
@ Somatik— 예, 부정적인 예측 및 뒤는 ECMAScript에서 지원되지 않습니다.
RobG 2014 년

참고 :이 예제는 Java에서 작동합니다. 모든 중괄호 안의 모든 값을 반환합니다.
멀티플렉서

13

이 시도

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
내가 원했던 정확히 :) 이것은 중괄호없이 결과를 반환 할 것이고, 다른 솔루션은 그것과 함께 반환 될 것입니다
Al-Mothafar

훌륭합니다. 여기에서 가장 좋은 답변입니다.
michal.jakubeczy

4

중괄호로 묶인 문자열 배열을 가져 오는 정규식은 첫 번째 항목을 찾는 것이 아니라 문자열에서 발생합니다.

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

4

나는 다른 답변을 살펴 보았고 중요한 논리가 누락 된 것 같습니다. 즉, 두 개의 연속 괄호 사이의 모든 항목을 선택하지만 괄호는 선택하지 않습니다.

그래서 여기 내 대답이 있습니다

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

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

더 간단한 .replace(/.*{(.*)}.*/, '$1')것은 불행히도 정규식이 일치하지 않으면 전체 문자열을 반환합니다. 위의 코드 조각은 일치를 더 쉽게 감지 할 수 있습니다.



2

이 정규식 재귀를 사용 {}하여 JSON 텍스트와 같은 다른 것까지 모든 것을 일치시킬 수 있습니다 .

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

좋습니다.하지만 이것은 중첩 된 중괄호 안의 내용 만 캡처합니다.
Dominic

콘텐츠에 ()가 포함 된 경우 캡처하지 않음
Mert Mertce 19

1

이것도 누군가의 문제를 해결하는 데 도움이됩니다.

{},와 같은 패턴을 가진 중괄호 ( ) 안의 내용을 분할합니다 {'day': 1, 'count': 100}.

예를 들면 :

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

산출:

[{'day': 1, 'count': 100}] [{'day': 2, 'count': 100}]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.