답변:
나는 다음과 같이 큰 성공을 거두었습니다.
(["'])(?:(?=(\\?))\2.)*?\1
중첩 따옴표도 지원합니다.
이것이 어떻게 작동하는지에 대한 더 깊은 설명을 원하는 사람들을 위해 다음은 사용자 ephemient 의 설명입니다 .
([""'])
따옴표와 일치;((?=(\\?))\2.)
백 슬래시가 존재한다면, 그것을 뒤섞 고, 그것이 발생하는지의 여부는 문자와 일치합니다.*?
여러 번 일치시킵니다 (마지막 따옴표를 먹지 않기 위해 탐욕스럽지 않습니다).\1
여는 데 사용 된 것과 동일한 견적을 찾습니다.
"foo\"
합니다. 미리보기 트릭은 ?
수량자를 소유하게 만듭니다 (정규 풍미가 ?+
구문 또는 원자 그룹화를 지원하지 않더라도 )
(["'])(?:\\.|[^\\])*?\1
일반적으로 다음 정규식 조각은 찾고 있습니다.
"(.*?)"
이것은 욕심없는 *를 사용합니까? 연산자는 다음 큰 따옴표를 포함하여 모든 것을 캡처합니다. 그런 다음 언어 별 메커니즘을 사용하여 일치하는 텍스트를 추출합니다.
파이썬에서는 다음을 수행 할 수 있습니다.
>>> import re
>>> string = '"Foo Bar" "Another Value"'
>>> print re.findall(r'"(.*?)"', string)
['Foo Bar', 'Another Value']
"hello \" world"
"(.*?(?<!\\))"
나는 갈 것이다 :
"([^"]*)"
는 [^ "] 를 제외한 모든 문자에 대한 정규식입니다 ' " '
나는 비 욕심 많은 조작을 통해이를 사용하는 이유는 그냥 확실히 나는 그것이 해결받을 수 있도록 그를 계속 찾고해야한다는 것입니다.
이스케이프 된 따옴표를 처리하는 두 가지 효율적인 방법을 살펴 보겠습니다. 이러한 패턴은 간결하거나 미학적으로 설계된 것이 아니라 효율적으로 설계되었습니다.
이러한 방법은 첫 번째 문자 구분을 사용하여 대체 비용없이 문자열에서 따옴표를 빠르게 찾습니다. (이 아이디어는 대체의 두 가지를 테스트하지 않고 따옴표가 아닌 문자를 빨리 버리는 것입니다.)
따옴표 사이의 내용은 반복되는 교체 대신 언롤 된 루프로 설명되어 더욱 효율적입니다. [^"\\]*(?:\\.[^"\\]*)*
따옴표가 균형이 맞지 않는 문자열을 처리하려면 분명히 [^"\\]*+(?:\\.[^"\\]*)*+
역 추적을 피하기 위해 소유 수량 자를 사용하거나이를 에뮬레이트하는 해결 방법을 사용할 수 있습니다 . 이스케이프 처리되지 않은 다음 인용 또는 문자열 끝까지 인용 된 부분이 시작 인용이 될 수 있도록 선택할 수도 있습니다. 이 경우 소유 수량자를 사용할 필요가 없으며 마지막 따옴표 만 선택하면됩니다.
주의 : 때때로 따옴표는 백 슬래시로 이스케이프되지 않고 따옴표를 반복하여 이스케이프됩니다. 이 경우 컨텐츠 서브 패턴은 다음과 같습니다.[^"]*(?:""[^"]*)*
패턴은 캡처 그룹과 역 참조 ( (["']).....\1
) 와 같은 것을 피하고 간단한 교대를 사용하지만 ["']
시작 부분 과 함께 사용합니다 .
펄 같은 :
["'](?:(?<=")[^"\\]*(?s:\\.[^"\\]*)*"|(?<=')[^'\\]*(?s:\\.[^'\\]*)*')
( (?s:...)
캡처하지 않은 그룹 내에서 dotall / singleline 모드를 켜는 구문 설탕입니다.이 구문이 지원되지 않는 경우 모든 패턴에 대해이 모드를 쉽게 켜거나 점을로 바꿀 수 있습니다 [\s\S]
)
(이 패턴이 작성되는 방식은 완전히 "수동식"이며 최종 엔진 내부 최적화를 고려하지 않습니다)
ECMA 스크립트 :
(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]*(?:\\[\s\S][^'\\]*)*')
POSIX 확장 :
"[^"\\]*(\\(.|\n)[^"\\]*)*"|'[^'\\]*(\\(.|\n)[^'\\]*)*'
또는 간단히 :
"([^"\\]|\\.|\\\n)*"|'([^'\\]|\\.|\\\n)*'
/pattern/
(대신 객체 표기법의 아무것도 탈출하지 않고 new RegExp("(?=[\"'])(?:\"[^\"\\\\]*...");
)
s
여기 를 제거 하고 패턴 어딘가에 (?s:
놓으면 Perl 버전을 사용할 수 있습니다 (?s)
.
: 허용 대답의 정규식은 자신을 sourrounding 인용 부호를 포함하여 값을 반환 "Foo Bar"
하고 "Another Value"
일치로합니다.
다음은 질문자가 요구 한대로 따옴표 사이 의 값만 반환하는 RegEx입니다 .
큰 따옴표 만 (캡처 그룹 # 1의 값 사용) :
"(.*?[^\\])"
작은 따옴표 만 (캡처 그룹 # 1의 값 사용) :
'(.*?[^\\])'
둘 다 (캡처 그룹 # 2의 값 사용) :
(["'])(.*?[^\\])\1
-
모든 지원 이스케이프 및 중첩 따옴표.
src="(.*)"
있었지만 분명히 마지막 "전에 모든 것을 선택하고 있었지만, REGEX는 src =" "내용 만 선택했지만 어떻게 이해하지 못했습니까?
특히,이 답변 중 어느 것도 반환 된 일치하는 따옴표 안의 텍스트 인 정규 표현식을 생성하지 않습니다. MA- 매든은 전체 경기가 아닌 캡처 된 그룹으로 내부 경기 만 시도합니다. 실제로 수행하는 한 가지 방법은 다음과 같습니다.
(?<=(["']\b))(?:(?=(\\?))\2.)*?(?=\1)
이에 대한 예제는이 데모에서 볼 수 있습니다 https://regex101.com/r/Hbj8aP/1
여기서 핵심은 시작 부분 ?<=
의 긍정적 인 전망 ( )과 끝 부분의 긍정적 인 전망 ( ?=
)입니다. lookbehind는 현재 문자 뒤에서 따옴표를 확인하기 위해 찾고 있습니다. 발견 된 경우 거기에서 시작한 다음 lookahead는 따옴표를 위해 앞의 문자를 확인하고 발견되면 해당 문자를 중지합니다. lookbehind 그룹 ( ["']
)은 괄호로 묶어 시작시 따옴표가 발견 된 그룹을 작성하며, 마지막 룩어 헤드 (?=\1)
에서 해당 따옴표를 찾을 때만 중지되도록 사용됩니다.
다른 복잡한 문제는 lookahead가 실제로 작은 따옴표를 사용하지 않기 때문에 시작 lookbehind에 의해 다시 발견되어 같은 줄의 끝과 시작 따옴표 사이의 텍스트가 일치한다는 것입니다. 여는 인용 부호 ( ["']\b
) 에 단어 경계를 두는 것이 이상적이지만 미리보기를 지나고 싶지만 그럴 수는 없다고 생각합니다. 내가 아담의 대답에서 직접 가져온 중간에 이스케이프 문자를 허용하는 비트.
(["'])(?:(?=(\\?))\2.)*?\1
위 의 패턴 은 작업을 수행하지만 성능이 걱정됩니다 (나쁘지는 않지만 더 나을 수 있음). ~ 20 % 더 빠릅니다.
패턴 "(.*?)"
이 불완전합니다. 이것을 읽는 모든 사람들을위한 나의 충고는 단지 IT를 사용하지 않는 것입니다 !!!
예를 들어 아래 문자열과 같이 많은 문자열을 캡처 할 수 없습니다 (필요한 경우 철저한 테스트 사례를 제공 할 수 있음).
$ string = '어떻게 지내? 나는
\'
'감사합니다, 벌금을 해요;
나머지는 위와 마찬가지로 "좋다".
성능과 정밀도를 모두 중요하게 생각한다면 다음 중 하나로 시작하십시오.
/(['"])((\\\1|.)*?)\1/gm
내 테스트에서 그것은 내가 만난 모든 문자열을 다루었지만 작동하지 않는 것을 발견하면 기꺼이 업데이트 할 것입니다.
나는 인용 부호를 피하면서 인용 부호 사이의 내용을 일치시키는 Eugen Mihailescu의 솔루션 을 좋아했습니다 . 그러나 탈출에 문제가 있음을 발견하고 다음 정규식을 수정했습니다.
(['"])(?:(?!\1|\\).|\\.)*\1
그것은 트릭을 수행하고 여전히 간단하고 유지 보수가 쉽습니다.
데모 (테스트 사례가 더 많으 므로 자유롭게 사용하고 확장하십시오).
추신 : 전체 일치 ( ) 의 인용 부호 사이 에 내용 $0
을 원하고 성능 패널티 사용을 두려워하지 않는 경우 :
(?<=(['"])\b)(?:(?!\1|\\).|\\.)*(?=\1)
불행히도 앵커로 인용 부호 \b
가 없으면 시작 인용 후 공백과 단어가 아닌 경계 문자와 잘 어울리지 않는 경계를 추가해야했습니다 .
또는 단순히 그룹을$2
추가 하고 문자열 형식을 추출 하여 초기 버전을 수정하십시오 .
(['"])((?:(?!\1|\\).|\\.)*)\1
PPS : 효율성에만 초점을 둔 경우 Casimir et Hippolyte의 솔루션으로 이동하십시오 . 좋은 것입니다.
-
은 경도 좌표와 같이 빼기 부호가있는 값을 누락합니다 .
더 많은 답변! 여기 내가 사용한 솔루션이 있습니다.
\"([^\"]*?icon[^\"]*?)\"
TLDR;
단어 아이콘 을 당신이 말한 따옴표와 짜잔에서 찾고있는 것으로 바꾸십시오 !
이것이 작동하는 방식은 키워드를 찾고 따옴표 사이의 다른 것을 신경 쓰지 않는 것입니다. EG :
id="fb-icon"
id="icon-close"
id="large-icon-close"
정규 표현식은 따옴표를 "
찾은 다음 "
찾을 때까지는 사용할 수 없는 문자 그룹을 찾고 icon
그렇지 않은 문자는 그룹 "
을 찾습니다."
name="value"
과를 name={"value"}
이 답변의 정규식 반환 이후 icon
/ value
(허용 대답과는 달리) 두 번째 그룹으로. 찾기 : =\"([^\"]*?[^\"]*?)\"
바꾸기 :={"$1"}
나는 Axeman의 더 광범위한 버전을 좋아했지만 문제가있었습니다 (예를 들어 일치하지 않았습니다)
foo "string \\ string" bar
또는
foo "string1" bar "string2"
올바르게 수정했습니다.
# opening quote
(["'])
(
# repeat (non-greedy, so we don't span multiple strings)
(?:
# anything, except not the opening quote, and not
# a backslash, which are handled separately.
(?!\1)[^\\]
|
# consume any double backslash (unnecessary?)
(?:\\\\)*
|
# Allow backslash to escape characters
\\.
)*?
)
# same character as opening quote
\1
string = "\" foo bar\" \"loloo\""
print re.findall(r'"(.*?)"',string)
그냥 사용해보십시오, 매력처럼 작동합니다!
\
스킵 문자를 나타냅니다
" foo bar" "loloo"
입니다. 나는 당신이 정규 표현식으로했던 것처럼 원시 문자열로 그것을 감싸려고했다고 생각합니다 r'"\" foo bar\" \"loloo\""'
. 필요할 때마다 SO의 뛰어난 서식 기능 을 사용하십시오 . 화장품 만이 아닙니다. 우리는 당신이 그들을 사용하지 않으면 말하려는 것을 말할 수 없습니다. 그리고 스택 오버플로에 오신 것을 환영합니다 !
도트 구문과 같이 특정 접미사 만있는 문자열을 찾으려면 다음을 시도하십시오.
\"([^\"]*?[^\"]*?)\".localized
.localized
접미사는 어디에 있습니까 ?
예:
print("this is something I need to return".localized + "so is this".localized + "but this is not")
그것은 캡처 "this is something I need to return".localized
하고 "so is this".localized
있지만 "but this is not"
.
Microsoft VBA 코더 의 하위 집합에 대한 보충 답변 은 라이브러리 Microsoft VBScript Regular Expressions 5.5
를 사용하며 다음 코드를 제공합니다.
Sub TestRegularExpression()
Dim oRE As VBScript_RegExp_55.RegExp '* Tools->References: Microsoft VBScript Regular Expressions 5.5
Set oRE = New VBScript_RegExp_55.RegExp
oRE.Pattern = """([^""]*)"""
oRE.Global = True
Dim sTest As String
sTest = """Foo Bar"" ""Another Value"" something else"
Debug.Assert oRE.test(sTest)
Dim oMatchCol As VBScript_RegExp_55.MatchCollection
Set oMatchCol = oRE.Execute(sTest)
Debug.Assert oMatchCol.Count = 2
Dim oMatch As Match
For Each oMatch In oMatchCol
Debug.Print oMatch.SubMatches(0)
Next oMatch
End Sub
나를 위해이 일을했습니다.
|([\'"])(.*?)\1|i
나는 다음과 같은 문장에서 사용했습니다.
preg_match_all('|([\'"])(.*?)\1|i', $cont, $matches);
그리고 그것은 잘 작동했습니다.
위의 모든 대답은 훌륭합니다 .... 모든 유니 코드 문자를 지원하지는 않습니다. ECMA 스크립트 (자바 스크립트)
Node 사용자 인 경우 모든 유니 코드 문자를 지원하는 수정 된 버전의 허용 된 응답을 원할 수 있습니다.
/(?<=((?<=[\s,.:;"']|^)["']))(?:(?=(\\?))\2.)*?(?=\1)/gmu
여기를 보십시오 .
? The preceding token is not quantifiable