[regex] RegEx : 따옴표 사이의 값 잡기

나는 이와 같은 가치가있다 :

"Foo Bar" "Another Value" something else

어떤 정규 표현식이 따옴표로 묶인 값을 반환 합니까 (예 : Foo BarAnother Value)?



답변

나는 다음과 같이 큰 성공을 거두었습니다.

(["'])(?:(?=(\\?))\2.)*?\1

중첩 따옴표도 지원합니다.

이것이 어떻게 작동하는지에 대한 더 깊은 설명을 원하는 사람들을 위해 다음은 사용자 ephemient 의 설명입니다 .

([""'])따옴표와 일치; ((?=(\\?))\2.)백 슬래시가 존재한다면, 그것을 뒤섞 고, 그것이 발생하는지의 여부는 문자와 일치합니다. *?여러 번 일치시킵니다 (마지막 따옴표를 먹지 않기 위해 탐욕스럽지 않습니다). \1여는 데 사용 된 것과 동일한 견적을 찾습니다.


답변

일반적으로 다음 정규식 조각은 찾고 있습니다.

"(.*?)"

이것은 욕심없는 *를 사용합니까? 연산자는 다음 큰 따옴표를 포함하여 모든 것을 캡처합니다. 그런 다음 언어 별 메커니즘을 사용하여 일치하는 텍스트를 추출합니다.

파이썬에서는 다음을 수행 할 수 있습니다.

>>> import re
>>> string = '"Foo Bar" "Another Value"'
>>> print re.findall(r'"(.*?)"', string)
['Foo Bar', 'Another Value']


답변

나는 갈 것이다 :

"([^"]*)"

[^ “] 를 제외한 모든 문자에 대한 정규식입니다 ‘
나는 비 욕심 많은 조작을 통해이를 사용하는 이유는 그냥 확실히 나는 그것이 해결받을 수 있도록 그를 계속 찾고해야한다는 것입니다.


답변

이스케이프 된 따옴표를 처리하는 두 가지 효율적인 방법을 살펴 보겠습니다. 이러한 패턴은 간결하거나 미학적으로 설계된 것이 아니라 효율적으로 설계되었습니다.

이러한 방법은 첫 번째 문자 구분을 사용하여 대체 비용없이 문자열에서 따옴표를 빠르게 찾습니다. (이 아이디어는 대체의 두 가지를 테스트하지 않고 따옴표가 아닌 문자를 빨리 버리는 것입니다.)

따옴표 사이의 내용은 반복되는 교체 대신 언롤 된 루프로 설명되어 더욱 효율적입니다. [^"\\]*(?:\\.[^"\\]*)*

따옴표가 균형이 맞지 않는 문자열을 처리하려면 분명히 [^"\\]*+(?:\\.[^"\\]*)*+역 추적을 피하기 위해 소유 수량 자를 사용하거나이를 에뮬레이트하는 해결 방법을 사용할 수 있습니다 . 이스케이프 처리되지 않은 다음 인용 또는 문자열 끝까지 인용 된 부분이 시작 인용이 될 수 있도록 선택할 수도 있습니다. 이 경우 소유 수량자를 사용할 필요가 없으며 마지막 따옴표 만 선택하면됩니다.

주의 : 때때로 따옴표는 백 슬래시로 이스케이프되지 않고 따옴표를 반복하여 이스케이프됩니다. 이 경우 컨텐츠 서브 패턴은 다음과 같습니다.[^"]*(?:""[^"]*)*

패턴은 캡처 그룹과 역 참조 ( (["']).....\1)같은 것을 피하고 간단한 교대를 사용하지만 ["']시작 부분 과 함께 사용합니다 .

펄 같은 :

["'](?:(?<=")[^"\\]*(?s:\\.[^"\\]*)*"|(?<=')[^'\\]*(?s:\\.[^'\\]*)*')

( (?s:...)캡처하지 않은 그룹 내에서 dotall / singleline 모드를 켜는 구문 설탕입니다.이 구문이 지원되지 않는 경우 모든 패턴에 대해이 모드를 쉽게 켜거나 점을로 바꿀 수 있습니다 [\s\S])

(이 패턴이 작성되는 방식은 완전히 “수동식”이며 최종 엔진 내부 최적화를 고려하지 않습니다)

ECMA 스크립트 :

(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*')

POSIX 확장 :

"[^"\\]*(\\(.|\n)[^"\\]*)*"|'[^'\\]*(\\(.|\n)[^'\\]*)*'

또는 간단히 :

"([^"\\]|\\.|\\\n)*"|'([^'\\]|\\.|\\\n)*'


답변

: 허용 대답의 정규식은 자신을 sourrounding 인용 부호를 포함하여 값을 반환 "Foo Bar"하고 "Another Value"일치로합니다.

다음은 질문자가 요구 한대로 따옴표 사이값만 반환하는 RegEx입니다 .

큰 따옴표 만 (캡처 그룹 # 1의 값 사용) :

"(.*?[^\\])"

작은 따옴표 만 (캡처 그룹 # 1의 값 사용) :

'(.*?[^\\])'

둘 다 (캡처 그룹 # 2의 값 사용) :

(["'])(.*?[^\\])\1

모든 지원 이스케이프 및 중첩 따옴표.


답변

특히,이 답변 중 어느 것도 반환 된 일치하는 따옴표 안의 텍스트 인 정규 표현식을 생성하지 않습니다. MA- 매든은 전체 경기가 아닌 캡처 된 그룹으로 내부 경기 만 시도합니다. 실제로 수행하는 한 가지 방법은 다음과 같습니다.

(?<=(["']\b))(?:(?=(\\?))\2.)*?(?=\1)

이에 대한 예제는이 데모에서 볼 수 있습니다 https://regex101.com/r/Hbj8aP/1

여기서 핵심은 시작 부분 ?<=의 긍정적 인 전망 ( )과 끝 부분의 긍정적 인 전망 ( ?=)입니다. lookbehind는 현재 문자 뒤에서 따옴표를 확인하기 위해 찾고 있습니다. 발견 된 경우 거기에서 시작한 다음 lookahead는 따옴표를 위해 앞의 문자를 확인하고 발견되면 해당 문자를 중지합니다. lookbehind 그룹 ( ["'])은 괄호로 묶어 시작시 따옴표가 발견 된 그룹을 작성하며, 마지막 룩어 헤드 (?=\1)에서 해당 따옴표를 찾을 때만 중지되도록 사용됩니다.

다른 복잡한 문제는 lookahead가 실제로 작은 따옴표를 사용하지 않기 때문에 시작 lookbehind에 의해 다시 발견되어 같은 줄의 끝과 시작 따옴표 사이의 텍스트가 일치한다는 것입니다. 여는 인용 부호 ( ["']\b) 에 단어 경계를 두는 것이 이상적이지만 미리보기를 지나고 싶지만 그럴 수는 없다고 생각합니다. 내가 아담의 대답에서 직접 가져온 중간에 이스케이프 문자를 허용하는 비트.


답변

매우 늦었지만 대답하고 싶습니다

(\"[\w\s]+\")

http://regex101.com/r/cB0kB8/1