따옴표 안에 있지 않은 모든 인스턴스와 일치하는 정규식
에서 이 Q / A는 , 주어진 정규 표현식 나는의 모든 인스턴스를 일치 여부 추론 하지 따옴표 안에 불가능하다. 즉, 이스케이프 된 따옴표 (예 :)와 일치 할 수 없습니다 "this whole \"match\" should be taken"
. 내가 모르는 방법이 내 문제를 해결할 것입니다.
그러나 그렇지 않다면 JavaScript에서 사용할 수있는 대안이 있는지 알고 싶습니다. 나는 대부분의 경우에 작동하는 우아한 솔루션을 제공하지 않습니다.
특히, .split () 및 .replace () 메서드로 작업 할 수있는 대안이 필요하지만 일반화 할 수있는 것이 가장 좋습니다.
예 :
입력 문자열 :
+bar+baz"not+or\"+or+\"this+"foo+bar+
+를 따옴표가 아닌 #으로 바꾸면 다음이 반환됩니다.
#bar#baz"not+or\"+or+\"this+"foo#bar#
모든 인스턴스는 따옴표 안에 있지 않은 정규식의 모든 인스턴스를 일치시킬 수 있습니다. 여기서 각 여는 따옴표는 다시 닫습니다. 위의 예에서와 같이 \+
.
여기서 중요한 관찰은 단어 짝수 개의 따옴표가 있습니다. 이 미리보기 어설 션으로 모델링 할 수 있습니다.
\+(?=([^"]*"[^"]*")*[^"]*$)
이제 이스케이프 된 따옴표를 계산하지 않습니다. 이것은 조금 더 복잡해집니다. [^"]*
다음 따옴표로 넘어가 는 대신 백 슬래시도 고려하고 [^"\\]*
. 백 슬래시 또는 따옴표에 도달 한 후 백 슬래시가 발생하면 다음 문자를 무시하거나 이스케이프 처리되지 않은 다음 따옴표로 넘어갑니다. 처럼 보이네요 (\\.|"([^"\\]*\\.)*[^"\\]*")
. 결합하면
\+(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)
나는 그것이 약간의 모호 라는 것을 인정합니다 . =)
Azmisov는이 질문을 부활 당신은 당신이 계획 any efficient alternative that could be used in JavaScript
하고 말하고 때문에 any elegant solutions that would work in most, if not all, cases
.
참조되지 않은 해결 방법이 있습니다.
대안과 쓸 때이 솔루션의 정규식은 놀랍도록 간단합니다.
"[^"]+"|(\+)
아이디어는 일치하지만 따옴표 안의 내용을 무시하여 해당 내용 (교대 왼쪽)을 무효화하는 것입니다. 오른쪽에서는 +
그룹 1로 무력화되지 않은 모든 항목을 설치 하고 기능은 그룹 1을 검사합니다. 다음은 전체 작업 코드입니다.
<script>
var subject = '+bar+baz"not+these+"foo+bar+';
var regex = /"[^"]+"|(\+)/g;
replaced = subject.replace(regex, function(m, group1) {
if (!group1) return m;
else return "#";
});
document.write(replaced);
동일한 원칙을 사용하여 일치 또는 분할 할 수 있습니다. 코드 샘플을 참조의 질문 및 가이드를 참조하십시오.
이것이 매우 일반적인 방법에 대한 다른 아이디어를 제공하기를 바랍니다. :)
빈 SDK는 어떻습니까?
위는 기술을 사용 설명서입니다. 정확한 필요에 따라 수 있습니다. 에 빈 문자열 텍스트이 포함되어있을 수 있다고 걱정되면 문자열 캡처 표현식 내의 수량 +
자를에서 *
다음으로 변경하십시오 .
"[^"]*"|(\+)
데모를 참조하십시오 .
이스케이프 된 따옴표는 어떻습니까?
다시 말하지만, 위는 기술을 마치 대답입니다. " 이 일치 무시 "을 필요에 정규식 맞게 조정할 수있을 뿐만 아니라 무시할 여러 표현식을 추가 할 수 있습니다. 예를 들어, 따옴표가 된 이스케이프 적절하게 무시 \\"|
되도록하려면 이스케이프 된 큰 따옴표를 일치 여부 (및 무시) 위해 다른 두하기 개 앞에 대체 를 추가하여 시작할 수 있습니다 .
다음으로, "[^"]*"
큰 따옴표로 묶인 문자열의 내용을 캡처 하는 섹션 내에서 이스케이프 된 큰 따옴표가 "
닫는 센티널로 바뀌기 전에 일치하는지 확인하기 위해 대체를 추가 할 수 있습니다."(?:\\"|[^"])*"
결과 표현식에는 세 가지 분기가 있습니다.
\\"
일치하고 무시하다"(?:\\"|[^"])*"
일치하고 무시하다(\+)
일치, 캡처 및 처리
다른 정규식 버전에서는 lookbehind로이 작업을 더 쉽게 수행 할 수 있지만 JS는이를 지원하지 않습니다.
전체 정규식은 다음과 같습니다.
\\"|"(?:\\"|[^"])*"|(\+)
참고
세 단계로 할 수 있습니다.
- 정규식 전역 대체를 사용하여 모든 문자열 본문 내용을 사이드 테이블로 추출합니다.
- 쉼표 번역 수행
- 정규식 전역 바꾸기를 사용하여 문자열 본문을 다시 바꿉니다.
아래 코드
// Step 1
var sideTable = [];
myString = myString.replace(
/"(?:[^"\\]|\\.)*"/g,
function (_) {
var index = sideTable.length;
sideTable[index] = _;
return '"' + index + '"';
});
// Step 2, replace commas with newlines
myString = myString.replace(/,/g, "\n");
// Step 3, swap the string bodies back
myString = myString.replace(/"(\d+)"/g,
function (_, index) {
return sideTable[index];
});
설정 후 실행하면
myString = '{:a "ab,cd, efg", :b "ab,def, egf,", :c "Conjecture"}';
당신은 얻어야한다
{:a "ab,cd, efg"
:b "ab,def, egf,"
:c "Conjecture"}
1 단계 이후에
myString = '{:a "0", :b "1", :c "2"}'
sideTable = ["ab,cd, efg", "ab,def, egf,", "Conjecture"];
따라서 myString의 유일한 쉼표는 문자열 외부입니다. 2 단계 : 쉼표를 줄 바꿈으로 바꿉니다.
myString = '{:a "0"\n :b "1"\n :c "2"}'
마지막으로 숫자 만 포함 된 문자열을 원래 내용으로 바꿉니다.
zx81의 대답이 가장 성능이 좋고 깨끗한 대답 인 것처럼 보이지만 이스케이프 된 따옴표를 올바르게 잡으려면 다음 수정이 필요합니다.
var subject = '+bar+baz"not+or\\"+or+\\"this+"foo+bar+';
과
var regex = /"(?:[^"\\]|\\.)*"|(\+)/g;
또한 이미 언급 된 "group1 === undefined"또는 "! group1". 특히 2. 원래 질문에서 물었던 모든 것을 실제로 고려하는 것이 중요해 보입니다.
이 방법은 이스케이프되지 않은 따옴표 쌍 외부에 이스케이프 된 따옴표가없는 문자열을 암시 적으로 요구한다는 점을 언급해야합니다.
참조 URL : https://stackoverflow.com/questions/6462578/regex-to-match-all-instances-not-inside-quotes
'ProgramingTip' 카테고리의 다른 글
NSMutableArray addObject가 작동하지 않습니다. (0) | 2021.01.09 |
---|---|
UINavigationBar 여러 줄 제목 (0) | 2021.01.09 |
가장 가까운 10으로 반올림하는 Javascript (0) | 2021.01.09 |
UITextField 텍스트에 그림자 효과 (0) | 2021.01.08 |
PHP에서 이미 "_"로 시작하는지 확인하는 방법은 무엇입니까? (0) | 2021.01.08 |