이스케이프 따옴표가있는 따옴표로 묶인 염색에 대한 정규식
" It's big \"problem "
을 사용 정규식 하여 하위 문자열 을 얻는 방법은 무엇입니까?
s = ' function(){ return " It\'s big \"problem "; }';
/"(?:[^"\\]|\\.)*"/
Regex Coach 및 PCRE Workbench에서 작동합니다.
JavaScript 테스트의 예 :
var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
var m = s.match(/"(?:[^"\\]|\\.)*"/);
if (m != null)
alert(m);
이것은 많은 리눅스 배포판에서 사용 가능한 nanorc.sample에서 온 것입니다. C 스타일의 구문 강조에 사용됩니다.
\"(\\.|[^\"])*\"
ePharaoh가 제공 한 답변은
/"([^"\\]*(\\.[^"\\]*)*)"/
작은 따옴표 또는 큰 따옴표로 묶은 키워드에 위의 내용을두고 다음을 사용하십시오.
/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/
"(?:\\"|.)*?"
교류 \"
와 .
탈출 인용을 통해 통과하면 게으른 정량의 동안 *?
은 인용 인용의 끝을지나 가지 않도록합니다. .NET Framework RE 클래스와 함께 작동
여기에 대부분의 솔루션은 대체 반복 경로, 즉 (A | B) *를 사용합니다.
일부 패턴 컴파일러는 재귀를 사용하여 구현에 큰 입력에서 스택 오버플로가 보관 수 있습니다.
예를 들어 Java : http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6337993
이와 같은 것 : "(?:[^"\\]*(?:\\.)?)*"
또는 Guy Bedford가 제공하는 것들은 대부분의 스택 오버플로를 피하면서 구문 분석 단계의 양을 줄입니다.
/"(?:[^"\\]++|\\.)*+"/
man perlre
Perl 5.22.0이 일련의 Linux 시스템 에서 직접 가져 왔습니다. 최적화로서, 정규식은 '포지티브'형식을 모두 사용 +
하고 *
역 추적을 방지합니다. 사전에 닫는 인용 부호가없는 경우에는 그렇지 않습니다.
이것은 PCRE에서 완벽하게 작동하며 StackOverflow와 함께 떨어지지 않습니다.
"(.*?[^\\])??((\\\\)+)?+"
설명 :
- 인용 된 모든 곳은 Char :로 시작합니다.
"
; - 임의의 수의 문자를 포함 할 수 있습니다.
.*?
{지연 일치}; 비 이스케이프 문자로 끝나는[^\\]
; - (2)은 Lazy (!)는 선택 사항입니다 ( ""). 그래서 :
(.*?[^\\])??
- 마지막으로, 인용 된 모든 페이지는 Char (
"
)로 끝나지만 , 짝수의 이스케이프 부호 쌍이 올 수 있습니다(\\\\)+
. 그리고 그것은 Greedy (!) 옵션입니다 :((\\\\)+)?+
{Greedy matching}, bacause 어디에나 비어 끝 쌍이 없어도됩니다!
/(["\']).*?(?<!\\)(\\\\)*\1/is
인용 된 동작 작동해야합니다.
다음은 "와 '모두에서 작동하며 처음에 쉽게 다른 사람을 추가하는 것입니다.
( "| ') (? : \\\ 1 | [^ \ 1]) *? \ 1
첫 번째 그룹에있는 역 참조 (\ 1)와 정확히 일치합니다 ( "또는 ').
http://www.regular-expressions.info/backref.html
이전에 다루지 않은 옵션은 다음과 가변합니다.
- 줄을 바꾸십시오.
- 반전 된 것에서 일치를 수행하십시오.
- 일치하는 동일한 것을 되 돌리십시오.
이스케이프 처리 된 열린 태그를 선택할 수있는 추가 개체가 있습니다.
다음은 신뢰할 수있는 가정 해 봅시다. String \"this "should" NOT match\" and "this \"should\" match"
여기서 \"this "should" NOT match\"
일치하지 "should"
않습니다. 그 위에 this \"should\" match
일치해야하며 일치 \"should\"
해야합니다.
첫 번째 예입니다.
// The input string.
const myString = 'String \\"this "should" NOT match\\" and "this \\"should\\" match"';
// The RegExp.
const regExp = new RegExp(
// Match close
'([\'"])(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))' +
'((?:' +
// Match escaped close quote
'(?:\\1(?=(?:[\\\\]{2})*[\\\\](?![\\\\])))|' +
// Match everything thats not the close quote
'(?:(?!\\1).)' +
'){0,})' +
// Match open
'(\\1)(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))',
'g'
);
// Reverse the matched strings.
matches = myString
// Reverse the string.
.split('').reverse().join('')
// '"hctam "\dluohs"\ siht" dna "\hctam TON "dluohs" siht"\ gnirtS'
// Match the quoted
.match(regExp)
// ['"hctam "\dluohs"\ siht"', '"dluohs"']
// Reverse the matches
.map(x => x.split('').reverse().join(''))
// ['"this \"should\" match"', '"should"']
// Re order the matches
.reverse();
// ['"should"', '"this \"should\" match"']
이제 RegExp에 대해 설명하겠습니다. 여기서 정규 서식을 쉽게 세 조각으로 나눌 수 있습니다. 다음과 같이 :
# Part 1
(['"]) # Match a closing quotation mark " or '
(?! # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\] # and a single escape
(?![\\]) # As long as that's not followed by an escape
)
# Part 2
((?: # Match inside the quotes
(?: # Match option 1:
\1 # Match the closing quote
(?= # As long as it's followed by
(?:\\\\)* # A pair of escape characters
\\ #
(?![\\]) # As long as that's not followed by an escape
) # and a single escape
)| # OR
(?: # Match option 2:
(?!\1). # Any character that isn't the closing quote
)
)*) # Match the group 0 or more times
# Part 3
(\1) # Match an open quotation mark that is the same as the closing one
(?! # As long as it's not followed by
(?:[\\]{2})* # A pair of escape characters
[\\] # and a single escape
(?![\\]) # As long as that's not followed by an escape
)
이것은 아마도 이미지 형식에서 훨씬 명확합니다 : Jex의 Regulex를 사용하여 생성하여
github의 이미지 (JavaScript Regular Expression Visualizer) 죄송합니다 . 이미지를 포함 할만 큼 평판이 높지 많은 지금은 링크입니다.
다음은 조금 더 고급 인이 개념을 사용하는 예제 함수의 요지입니다. https://gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js
정규 표현식이 모든 문자열에 대한 은색 총알이 아님을 기억해야합니다. 어떤 것들은 커서와 선형, 수동, 탐색으로 더 간단합니다. CFL은 매우 하찮게 트릭을 할 것이다, 그러나 많은 CFL 구현 (AFAIK)이 없습니다.
https://stackoverflow.com/a/10786066/1794894 의 더 광범위한 버전
/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/
이 버전에는
- 최소 견적 길이 50
- 추가 유형의 따옴표 (열기
“
및 닫기”
)
정규 표현식에 엉망이 되어이 정규 표현식으로 끝났습니다. (작동 방식을 묻지 마십시오.
"(([^"\\]?(\\\\)?)|(\\")+)+"
처음부터 검색하면 작동할까요?
\"((\\\")|[^\\])*\"
일부 파일의 구문 분석을 방해 할 수있는 인용 된 문자열을 제거하려는 비슷한 문제가 발생했습니다.
나는 당신이 생각 해낼 수있는 복잡한 정규식을 능가하는 2 단계 솔루션으로 끝났습니다.
line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful
읽기 쉽고 아마도 더 효율적일 것입니다.
참고 URL : https://stackoverflow.com/questions/249791/regex-for-quoted-string-with-escaping-quotes
'IT' 카테고리의 다른 글
PHP에서 클래스 메소드의 기본 가시성 (0) | 2020.07.29 |
---|---|
JPEG 최적화 도구? (0) | 2020.07.29 |
-performSelector 사용 : 대 메소드 호출 (0) | 2020.07.29 |
루프 후 버퍼 버퍼 / 빌더 지우기 (0) | 2020.07.29 |
일반적인 상태 머신 구현 (0) | 2020.07.29 |