자바 스크립트 정규식-대안을 보시겠습니까?


143

다음은 대부분의 정규식 구현에서 잘 작동하는 정규식입니다.

(?<!filename)\.js$

filename.js를 제외하고 .js로 끝나는 문자열의 .js와 일치합니다.

자바 스크립트에는 정규 표현식이 없습니다. 누구나 동일한 결과를 얻고 자바 스크립트에서 작동하는 대체 정규식을 조합 할 수 있습니까?

다음은 몇 가지 생각이지만 도우미 기능이 필요합니다. 나는 정규식으로 그것을 달성하기를 바랐다 : http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript


3
특정 파일 이름이나 파일 이름 목록 만 확인해야하는 경우 두 가지 확인 만 사용하면 안됩니다. .js로 끝나는 지 확인하고 그렇다면 .files.js와 일치하지 않는지 확인하십시오.
si28719e

3
업데이트 : 최신 공개 Chrome 버전 (v62)에는 기본적으로 실험적인 룩 베어가 포함되어 있습니다 .D 그러나 룩 허브 는 여전히 제안 단계 3 인 github.com/tc39/proposal-regexp-lookbehind에 있습니다. 따라서 모든 곳에서 JavaScript가 지원할 때까지 시간이 걸릴 수 있습니다. 프로덕션 환경에서 사용하는 것이 더 좋습니다!
Eirik Birkeland

2
# 업데이트 : ES2018을 포함 lookbehind 주장 플러스 : - DOTALL의 모드 (S 플래그) - Lookbehind 주장 - 명명 된 캡처 그룹 - 유니 코드 속성 탈출을
애슐리 Coolman

2
그냥 사용 (?<=thingy)thingy에 대한 긍정적 인 lookbehind(?<!thingy)thingy대한 부정적인 lookbehind . 이제는 그들을 지원합니다.
Константин Ван

7
@ K._ 2018 년 2 월 현재 그것은 사실이 아닙니다 !! 브라우저와 엔진이 사양을 구현해야하기 때문에 시간이 필요합니다 (현재 초안).
Andre Figueiredo

답변:


64

^(?!filename).+\.js 나를 위해 일한다

에 대해 테스트 :

  • test.js 일치
  • blabla.js 일치
  • filename.js가 일치하지 않습니다

이 정규식에 대한 적절한 설명 은 단어가 포함되지 않은 문자열과 일치하는 정규식 에서 찾을 수 있습니까?

Javascript 버전 1.5 부터 사용 가능 하며 모든 주요 브라우저에서 지원됩니다.

filename.js가 아닌 filename2.js 및 2filename.js와 일치하도록 업데이트 되었습니다.

(^(?!filename\.js$).).+\.js


5
이 질문은 약간 다른 문제에 대한 이야기와 연결되어 있습니다 : 대상 단어가 포함되지 않은 문자열 일치 어디서나 . 대상 단어로 시작 하지 않는 문자열을 일치시키는 것이 훨씬 간단 합니다.
Alan Moore

filename2.js 또는 filenameddk.js 또는 이와 유사한 경우에만 누락됩니다. 일치하지 않지만 일치해야합니다.
다니엘

9
@daniel 당신은 예견이 아닌 예견을 요구했는데 왜이 대답을 받아들였습니까?
hek2mgl

1
주어진 것과 일치하지 않습니다a.js
inetphantom

1
lookbehind가있는 원래 정규식은과 일치하지 않지만 2filename.js여기에 제공된 정규식은 일치 합니다. 더 적절한 것입니다 ^(?!.*filename\.js$).*\.js$. *.js 이는를 제외한 모든 항목과 일치 함을 의미합니다 *filename.js.
17시

153

편집 : ECMAScript 2018부터 lookbehind 어설 션 (무제한)도 기본적으로 지원됩니다 .

이전 버전에서는 다음을 수행 할 수 있습니다.

^(?:(?!filename\.js$).)*\.js$

이것은 lookbehind 표현식이 내재적으로 수행하는 것을 명시 적으로 수행합니다. lookbehind 표현식과 정규 표현식이 일치하지 않는 경우 문자열의 각 문자를 확인한 다음 해당 문자 만 일치시킵니다.

^                 # Start of string
(?:               # Try to match the following:
 (?!              # First assert that we can't match the following:
  filename\.js    # filename.js 
  $               # and end-of-string
 )                # End of negative lookahead
 .                # Match any character
)*                # Repeat as needed
\.js              # Match .js
$                 # End of string

또 다른 편집 :

이 목표를 달성하는 훨씬 쉬운 방법이 있다고 말하면서 (특히이 답변이 너무 많이 찬성 되었기 때문에) 고통 스럽습니다. 모든 캐릭터에서 미리보기를 확인할 필요가 없습니다.

^(?!.*filename\.js$).*\.js$

마찬가지로 작동합니다.

^                 # Start of string
(?!               # Assert that we can't match the following:
 .*               # any string, 
  filename\.js    # followed by filename.js
  $               # and end-of-string
)                 # End of negative lookahead
.*                # Match any string
\.js              # Match .js
$                 # End of string

선행 문자가있는 경우를 제외하고는 대부분의 경우에 작동합니다. --- 말했듯이, lookbehind는 내가 지금까지 알지 못했던 것과 같은 한계를 가지고 있습니다 ...
daniel

9
@daniel : 글쎄, 정규 표현식 (lookbehind 포함)도 일치하지 않습니다 2filename.js. 내 정규 표현식은 예제 정규 표현식과 정확히 동일한 경우에 일치합니다.
Tim Pietzcker

내 순진함을 용서하지만 캡처되지 않은 그룹에 대한 사용이 있습니까? 나는 항상 문자열의 대체를 위해 참조를 수집하려고 할 때만 유용하다는 것을 알고있었습니다. 내가 아는 한, 이것도 작동합니다 ^ (?! filename \ .js $). * \. js $
답변을 원합니다

1
그 정규 표현식은 문자열의 시작 부분에서만 "filename.js"를 확인합니다. 그러나 ^(?!.*filename\.js$).*\.js$작동합니다. ncgroup이 여전히 필요할 수있는 상황을 생각하려고 시도하는 중 ...
Tim Pietzcker

이 접근 방식은 다음과 같이 요약 할 수 있습니다. X 뒤를 보는 대신 X 앞에 오는 모든 문자를 미리 보시겠습니까?
Sarsaparilla 2016 년

25

int앞에 오지 않는 것을 모두 찾고 싶다고 가정 해 봅시다 unsigned.

부정적인 표정을 지원합니다.

(?<!unsigned )int

부정적인 표정을 지원하지 않는 경우 :

((?!unsigned ).{9}|^.{0,8})int

기본적으로 아이디어는 n 개의 선행 문자를 잡고 부정적인 미리보기와 일치하는 것을 제외하고 n 개의 선행 문자가없는 경우와 일치시키는 것입니다. (여기서 n은 look-behind 길이입니다.)

따라서 문제의 정규 표현식 :

(?<!filename)\.js$

다음과 같이 번역됩니다 :

((?!filename).{8}|^.{0,7})\.js$

관심있는 문자열의 정확한 지점을 찾거나 특정 부분을 다른 것으로 바꾸지 않으려면 캡처 그룹을 가지고 놀아야 할 수도 있습니다.


난 그냥이 변환 : (?<!barna)(?<!ene)(?<!en)(?<!erne) (?:sin|vår)e?(?:$| (?!egen|egne))(?!barna).(?!erne).(?!ene).(?!en).. (?:sin|vår)e?(?:$| (?!egen|egne))있는 내 요구에 대한 트릭을 수행합니다. 이것을 또 다른 "실제"시나리오로 제공하십시오. 링크
Eirik Birkeland

당신이 생각한 것 :((?!unsigned ).{9}|^.{0,8})int
pansay

@pansay 네. 감사합니다. 방금 답변을 수정했습니다.
카밀 쇼트

2
텍스트 내에서 깊이 일치 해야하는 경우 (초기 ^는 비실용적 인 경우)보다 일반적인 답변을 주셔서 감사합니다!
Milos Mrdovic

5

앞뒤로 볼 수 있으면 먼저 문자열을 뒤집은 다음 살펴볼 수 있습니다. 물론 더 많은 작업을 수행해야합니다.


8
이 답변은 실제로 약간의 개선을 사용할 수 있습니다. 그것은 나에게 의견처럼 보인다.
mickmackusa

2

이것은 Tim Pietzcker의 답변 과 동등한 솔루션 입니다 (동일한 답변의 의견 참조).

^(?!.*filename\.js$).*\.js$

*.js제외하고 일치하는 것을 의미 *filename.js합니다.

이 솔루션을 사용하려면 제외 패턴이 제외하는 패턴을 확인한 다음 제외 패턴으로 이러한 패턴을 정확하게 제외 할 수 있습니다.


-1

아래는 'Michael'을 이름으로하는 사람들의 성을 캡처하는 방법을 보여주는 JavaScript 대안의 긍정적 인 모습입니다.

1)이 텍스트가 주어지면 :

const exampleText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";

Michael이라는 성의 배열을 얻습니다. 결과는 다음과 같아야합니다.["Jordan","Johnson","Green","Wood"]

2) 해결책 :

function getMichaelLastName2(text) {
  return text
    .match(/(?:Michael )([A-Z][a-z]+)/g)
    .map(person => person.slice(person.indexOf(' ')+1));
}

// or even
    .map(person => person.slice(8)); // since we know the length of "Michael "

3) 솔루션 확인

console.log(JSON.stringify(    getMichaelLastName(exampleText)    ));
// ["Jordan","Johnson","Green","Wood"]

데모 데모 : http://codepen.io/PiotrBerebecki/pen/GjwRoo

아래 스 니펫을 실행하여 사용해 볼 수도 있습니다.

const inputText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";



function getMichaelLastName(text) {
  return text
    .match(/(?:Michael )([A-Z][a-z]+)/g)
    .map(person => person.slice(8));
}

console.log(JSON.stringify(    getMichaelLastName(inputText)    ));

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.