자바스크립트에서 동등한 것에 대한 부정적인 뒤보기
자바스크립트 정규 표현식에서 부정적인 느낌을 얻을 수 있는 방법이 있습니까?특정 문자 집합으로 시작하지 않는 문자열을 일치시켜야 합니다.
문자열 시작 부분에 일치하는 부분이 있으면 실패하지 않고 이렇게 하는 regex를 찾을 수 없는 것 같습니다.부정적인 시선이 유일한 답인 것 같지만 자바스크립트에는 없습니다.
이것은 제가 일하고 싶은 정규 근무제입니다만, 그렇지 않습니다.
(?<!([abcdefg]))m
따라서 jim 또는 m의 m과 일치하지만 jam은 일치하지 않습니다.
2018년부터 Look behind Assertions는 ECMA스크립트 언어 사양의 일부입니다.
// positive lookbehind
(?<=...)
// negative lookbehind
(?<!...)
2018년 이전 답변
자바스크립트는 네거티브 룩어헤드를 지원하므로 이를 위한 한 가지 방법은 다음과 같습니다.
입력 문자열을 반전합니다.
역수와 일치.
성냥을 되돌리고 다시 포맷합니다.
const reverse = s => s.split('').reverse().join('');
const test = (stringToTests, reversedRegexp) => stringToTests
.map(reverse)
.forEach((s,i) => {
const match = reversedRegexp.test(s);
console.log(stringToTests[i], match, 'token:', match ? reverse(reversedRegexp.exec(s)[0]) : 'Ø');
});
예 1:
@andrew-ensley의 질문에 따라:
test(['jim', 'm', 'jam'], /m(?!([abcdefg]))/)
출력:
jim true token: m
m true token: m
jam false token: Ø
예 2:
@neaumusic comment ()max-height
그러나 그렇지는line-height
, 상징적 존재height
):
test(['max-height', 'line-height'], /thgieh(?!(-enil))/)
출력:
max-height true token: height
line-height false token: Ø
Look behind Assertions는 2018년 ECMA스크립트 사양에 승인되었습니다.
긍정적인 사용법 이면:
console.log(
"$9.99 €8.47".match(/(?<=\$)\d+\.\d*/) // Matches "9.99"
);
부정적인 사용법:
console.log(
"$9.99 €8.47".match(/(?<!\$)\d+\.\d*/) // Matches "8.47"
);
플랫폼 지원
- ✔️ V8
- ✔️거미원숭이
- ✔ ️ 자바스크립트코어: 기능이 병합되었습니다
- ❌ Chakra: 마이크로소프트사에서 작업중이었으나 현재 Chakra는 V8을 선호하여 포기되었습니다.
- ❌ 인터넷 익스플로러
- ❌ 79 이전 버전의 Edge(Edge 기반 버전HTML+차크라)
당신이 모든 것을 찾고 싶어한다고 가정해봅시다.int
에 뒤지지 않는unsigned
:
부정적인 전망에 대한 지원으로:
(?<!unsigned )int
부정적인 전망에 대한 지원이 없는 경우:
((?!unsigned ).{9}|^.{0,8})int
기본적으로 선행 문자를 잡고 부정적인 전망으로 매칭을 배제하는 것이 아이디어지만 선행 문자 n개가 없는 경우도 매칭합니다.(여기서 n은 뒤를 보는 길이입니다).
그럼 문제의 정규군은?
(?<!([abcdefg]))m
다음과 같이 번역됩니다.
((?!([abcdefg])).|^)m
캡처 그룹을 사용하여 관심 있는 문자열의 정확한 위치를 찾거나 특정 부분을 다른 것으로 교체하려는 경우가 있습니다.
Mijoja의 전략은 당신의 특정한 경우에는 효과가 있지만 일반적인 경우에는 효과가 없습니다.
js>newString = "Fall ball bill balll llama".replace(/(ba)?ll/g,
function($0,$1){ return $1?$0:"[match]";});
Fa[match] ball bi[match] balll [match]ama
여기에 더블 L을 맞추는 것이 목표이지만 "ba" 앞에 올 경우에는 그렇지 않은 예가 있습니다."ball"이라는 단어에 주목하세요. 진정한 뒤의 모습은 첫 번째 2l를 억제해야 하지만 두 번째 쌍과 일치해야 합니다.그러나 처음 2l를 일치시킨 다음 해당 일치를 false positive로 무시하면 regexp 엔진은 해당 일치가 끝날 때부터 진행되며 false positive 내의 모든 문자를 무시합니다.
사용하다
newString = string.replace(/([abcdefg])?m/, function($0,$1){ return $1?$0:'m';});
문자 집합을 부정하여 캡처하지 않는 그룹을 정의할 수 있습니다.
(?:[^a-g])m
할 겁니다...모든 것이 일치할 것입니다.m
그 어떤 글자도 앞에 붙지 않았습니다.
이것이 제가 성취한 방법입니다.str.split(/(?<!^)@/)
Node.js 8의 경우(뒤보기를 지원하지 않음):
str.split('').reverse().join('').split(/@(?!$)/).map(s => s.split('').reverse().join('')).reverse()
작동? 네 (유니코드 테스트 안됨)불쾌해요?네.
Mijoja의 아이디어를 따라 그리고 JasonS에 의해 노출된 문제들로부터 끌어내어, 나는 이 아이디어를 가지고 있었습니다; 나는 조금 확인했지만 나 자신을 확신할 수 없기 때문에 js regex에서 나보다 더 전문가인 누군가의 검증이 좋을 것 같습니다 :)
var re = /(?=(..|^.?)(ll))/g
// matches empty string position
// whenever this position is followed by
// a string of length equal or inferior (in case of "^")
// to "lookbehind" value
// + actual value we would want to match
, str = "Fall ball bill balll llama"
, str_done = str
, len_difference = 0
, doer = function (where_in_str, to_replace)
{
str_done = str_done.slice(0, where_in_str + len_difference)
+ "[match]"
+ str_done.slice(where_in_str + len_difference + to_replace.length)
len_difference = str_done.length - str.length
/* if str smaller:
len_difference will be positive
else will be negative
*/
} /* the actual function that would do whatever we want to do
with the matches;
this above is only an example from Jason's */
/* function input of .replace(),
only there to test the value of $behind
and if negative, call doer() with interesting parameters */
, checker = function ($match, $behind, $after, $where, $str)
{
if ($behind !== "ba")
doer
(
$where + $behind.length
, $after
/* one will choose the interesting arguments
to give to the doer, it's only an example */
)
return $match // empty string anyhow, but well
}
str.replace(re, checker)
console.log(str_done)
개인적인 산출물:
Fa[match] ball bi[match] bal[match] [match]ama
부름이 원칙입니다checker
두 문자 사이의 문자열의 각 지점에서 해당 위치가 다음의 시작점이 될 때마다:
--- 필요하지 않은 것의 크기의 부분 문자열(여기서)'ba'
,따라서..
) (해당 크기를 알고 있다면, 그렇지 않으면 아마 더 어려울 것입니다.)
--- --- 또는 문자열의 시작일 경우 그보다 작습니다.^.?
이 일을 계기로
--- 실제로 구해야 할 것(여기)'ll'
).
전화할 때마다checker
, 이전의 값을 확인하기 위한 테스트가 있을 것입니다.ll
우리가 원하지 않는 것이 아닙니다 (!== 'ba'
); 그렇다면 다른 함수를 호출하고, 이 함수여야 합니다 (doer
str 에합니다 하는 데 만약 이것이 목적이거나 더 일반적으로 검색 결과를 수동으로 처리하는 데 필요한 데이터를 입력합니다.str
.
여기서 우리는 문자열을 바꾸어서 우리는 주어진 위치를 상쇄하기 위해 길이의 차이를 추적할 필요가 있었습니다.replace
, 모두 에 계산하여str
, 그 자체는 절대 변하지 않습니다.
원시 문자열은 불변이기 때문에, 우리는 그 변수를 사용할 수 있었습니다.str
전체 연산의 결과를 저장하는 것이지만, 나는 이미 교체로 인해 복잡해진 예제가 다른 변수로 더 명확할 것이라고 생각했습니다.str_done
).
공연적인 면에서는 꽤 가혹할 것이라고 생각합니다. "를 ""로 무의미하게 대체하는 모든 것들,this str.length-1
시간, 그리고 여기 수동으로 교체하는 것이 많은 절단을 의미합니다.아마도 이 특정한 위의 경우, 우리가 삽입하고 싶은 곳 주변에서 줄을 한 번만 잘라냄으로써 그룹화될 수 있을 것입니다.[match]
그리고..join()
와 함께.[match]
그 자체.
또 하나는 더 복잡한 사건들을 어떻게 다룰지 모른다는 거죠. 즉, 뒤에 보이는 가짜에 대한 복잡한 가치들 말이죠.길이는 아마도 가장 문제가 많은 데이터일 것입니다.
그리고,checker
, $back에 대해 여러 개의 원하지 않는 값이 발생할 가능성이 있는 경우, 우리는 외부에서 또 다른 regex(캐싱(생성)될)를 사용하여 테스트를 수행해야 합니다.checker
를 호출할 때마다 동일한 regex 개체가 생성되지 않도록 하는 것이 최선입니다.checker
그것이 우리가 회피하고자 하는 것인지 아닌지를 알 수 있습니다.
제가 분명히 했길 바랍니다; 주저하지 않는다면, 저는 더 잘 노력할 것입니다.:)
당신의 케이스를 이용해서, 만약 당신이 대체하기를 원한다면, m
예를 들어 그것을 대문자로 바꾸는 것과 같이.M
, 캡처 그룹에서 set을 negative 할 수 있습니다.
경기([^a-g])m
, 대신에$1M
"jim jam".replace(/([^a-g])m/g, "$1M")
\\jiM jam
([^a-g])
어떤 문자와도 일치합니다().^
)에서a-g
범위를 지정하고 첫 번째 캡처 그룹에 저장하여 다음과 같이 액세스할 수 있습니다.$1
.
그래서 우리는 발견합니다.im
인에jim
로 교체합니다.iM
결과적으로jiM
.
앞서 언급했듯이 자바스크립트는 이제 뒤를 볼 수 있게 되었습니다.이전 브라우저에서는 여전히 해결 방법이 필요합니다.
내 머릿속에는 정확하게 결과를 전달하는 뒤를 돌아보지 않고는 레젝스를 찾을 방법이 없을 거라고 장담합니다.당신이 할 수 있는 일은 그룹들과 함께 일하는 것뿐입니다.정규군이 있다고 가정해 보겠습니다.(?<!Before)Wanted
,어디에Wanted
당신이 매치하고 싶은 regex와.Before
는 일치하기 전에 무엇이 없어야 하는지를 카운트하는 정규군입니다.당신이 할 수 있는 최선은 레지렉스를 부정하는 것입니다.Before
regex를 사용합니다.NotBefore(Wanted)
. 원하는 결과는 첫 번째 그룹입니다.$1
.
고객님의 경우Before=[abcdefg]
부정하기 쉬운.NotBefore=[^abcdefg]
. 그래서 정규군은[^abcdefg](m)
. 당신이 필요한 위치는Wanted
, 당신은 조를 짜야합니다.NotBefore
또한, 원하는 결과가 두 번째 그룹입니다.
일치하는 경우Before
패턴이 일정한 길이를 가지런히n
, 즉, 패턴이 반복되는 토큰을 포함하지 않는 경우, 당신은 다음을 부정하는 것을 피할 수 있습니다.Before
패턴을 만들어 정규식을 사용합니다.(?!Before).{n}(Wanted)
, 하지만 여전히 첫번째 그룹을 사용하거나 정규 표현을 사용해야 합니다.(?!Before)(.{n})(Wanted)
두번째 그룹을 사용합니다.이 예제에서 패턴은Before
실제로는 1이라는 고정된 길이를 가지고 있으므로 regex를 사용합니다.(?![abcdefg]).(m)
아니면(?![abcdefg])(.)(m)
. 모든 일치 항목에 관심이 있는 경우 다음을 추가합니다.g
플래그, 내 코드 스니펫 참조:
function TestSORegEx() {
var s = "Donald Trump doesn't like jam, but Homer Simpson does.";
var reg = /(?![abcdefg])(.{1})(m)/gm;
var out = "Matches and groups of the regex " +
"/(?![abcdefg])(.{1})(m)/gm in \ns = \"" + s + "\"";
var match = reg.exec(s);
while(match) {
var start = match.index + match[1].length;
out += "\nWhole match: " + match[0] + ", starts at: " + match.index
+ ". Desired match: " + match[2] + ", starts at: " + start + ".";
match = reg.exec(s);
}
out += "\nResulting string after statement s.replace(reg, \"$1*$2*\")\n"
+ s.replace(reg, "$1*$2*");
alert(out);
}
이렇게 하면 효과적입니다.
"jim".match(/[^a-g]m/)
> ["im"]
"jam".match(/[^a-g]m/)
> null
예제 검색 및 바꾸기
"jim jam".replace(/([^a-g])m/g, "$1M")
> "jiM jam"
이 작업을 수행하려면 음의 뒤로 가기 문자열이 1자 길이여야 합니다.
언급URL : https://stackoverflow.com/questions/641407/negative-lookbehind-equivalent-in-javascript
'programing' 카테고리의 다른 글
Visual Studio에서 MySQL 데이터 원본에 연결하는 방법 (0) | 2023.10.29 |
---|---|
Flex Slider - 두 슬라이더에 대해 동일한 컨트롤을 추가하는 방법 (0) | 2023.10.29 |
오류 1064:SQL 구문에 오류가 있습니다. MariaDB 서버 버전에 해당하는 설명서에서 다음에 사용할 올바른 구문을 확인하십시오. (0) | 2023.10.29 |
PHP에서 PDO를 통해 MySQL 쿼리를 루프하려면 어떻게 해야 합니까? (0) | 2023.10.29 |
C에서 : 연산자의 사용 (0) | 2023.10.29 |