주어진 접미사로 끝나지 않는 문자열에 대한 정규식


190

어떤 조건으로 끝나지 않는 문자열과 일치하는 적절한 정규식을 찾을 수 없었습니다 . 예를 들어으로 끝나는 항목과 일치하고 싶지 않습니다 a.

이 일치

b
ab
1

일치하지 않습니다

a
ba

나는 정규식이 끝 $을 표시하기 위해 끝나야한다는 것을 알고 있지만, 그것을 앞두고 무엇을 해야할지 모르겠습니다.

편집 : 원래 질문은 내 경우에는 합법적 인 예가 아닌 것 같습니다. 그래서 : 둘 이상의 캐릭터를 처리하는 방법? 끝나지 않는 말이 ab있습니까?

이 스레드를 사용 하여이 문제를 해결할 수있었습니다 .

.*(?:(?!ab).).$

이것의 단점은 있지만 한 문자의 문자열과 일치하지 않습니다.


5
입니다 하지 링크 된 질문의 중복 - 마지막에만에 대한 매칭은 문자열 내에서 어디 일치가 아닌 다른 구문이 필요합니다. 여기에 최고의 답변을보십시오.
jaustin

동의합니다. 이것은 연결된 질문과 중복 되지 않습니다 . 위의 "표시"를 어떻게 제거 할 수 있을까요?
Alan Cabrera

내가 볼 수있는 그러한 링크는 없습니다.
Alan Cabrera

답변:


252

당신은 우리에게 언어를주지 않지만, 정규 표현식 지원 이 어설 션 뒤에 숨어 있다면 이것이 필요한 것입니다.

.*(?<!a)$

(?<!a)문자열 (또는 m수정자가있는 행)이 끝나기 전에 문자 "a"가 없는지 확인 하는 부정 된 비하인드 어설 션입니다 .

Regexr에서 여기를 참조하십시오

문자열을 검사하고 문자 클래스가 아니기 때문에 다른 문자로 쉽게 확장 할 수 있습니다.

.*(?<!ab)$

이것은 "ab"로 끝나지 않는 것과 일치 합니다. Regexr 에서 참조하십시오.


1
RegexPAL을 모르지만 정규 표현식은 모든 언어에서 다르며, 어설 션은 모든 기능이 지원하지 않는 고급 기능입니다.
stema

7
regexpal은 자바 스크립트 기반의 정규식 테스터이며, 자바 스크립트는 슬픈

lookbehinds는 정규식 (javascript)에서 지원되지 않습니다
Stealth Rabbi

1
JS의 lookbehinds 부족으로 인해 울었습니다. 서버 측을 사용하는 경우 NPM 또는 이와 유사한 PCRE 모듈을 사용하여 직접 사용할 수 있습니다 (바인딩 세트이므로 프런트 엔드를 사용할 수 없다고 생각합니다)
Eirik Birkeland

내다 / lookbehind 주장의 더 많은 종류의 : stackoverflow.com/q/2973436/12484
존 슈나이더

76

not ( ^) 기호를 사용하십시오 .

.*[^a]$

^괄호의 시작 부분에 기호 를 넣으면 "괄호 안의 것을 제외한 모든 것"을 의미합니다. $단순히 끝의 닻입니다.

여러 문자의 경우 모두 고유 한 문자 세트에 넣으십시오.

.*[^a][^b]$

1
+1, 이것이 빈 문자열과 일치하지 않는다는 경고 (의도적이거나 그렇지 않을 수도 있음)를 의미하므로 의미는 "괄호 안에없는 모든 문자"입니다.
Fred Foo

3
@ 0A0D : 공백을 포함하는 문자열은 빈 문자열이 아닙니다.
Fred Foo

7
사실의 최대 논쟁이 아니다 실제로 @ 0A0D,
tckmn

8
@Doorknob :이 일치하지 않는 aecb.
Fred Foo

1
아니요, "acb"도 허용되지 않습니다.
Menno

49

".tmp"로 끝나지 않는 파일을 검색하려면 다음 정규식을 사용하십시오.

^(?!.*[.]tmp$).*$

정규식 테스터로 테스트 한 결과는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오


1
이것은 흥미 롭습니다. 왜 이것이 효과가 있고 왜 ^.*(?![.]tmp$)그렇지 않습니까?
우 카슈 자로 다

4
초반 .*은 이미 전체 문자열과 일치하므로 나머지 제외는 더 이상 작동하지 않습니다.
FiveO

내 목적으로, 이것은 효과가 있었고 다른 답변은 효과가 없었습니다. 감사!
David Moritz

8
.*[^a]$

위의 정규 표현식은로 끝나지 않는 문자열과 일치 a합니다.


원래 예제가 내 사례와 완전히 일치하지 않는 것 같아서 질문을 확장했습니다. 당신은 그것을 해결할 수 있습니까?
Menno

5

이 시도

/.*[^a]$/

[]문자 클래스를 의미하고, ^반전 캐릭터 클래스는 모든하지만 일치하도록 a.


1

문제는 오래되었지만 여기에 게시하는 더 나은 솔루션을 찾을 수 없습니다. 모든 USB 드라이브를 찾고 파티션을 나열하지 않으면 결과에서 "part [0-9]"가 제거됩니다. 나는 두 개의 grep을 끝내고 마지막은 결과를 부정합니다.

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$"

내 시스템에서 결과 :

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

파티션 만 원하는 경우 다음을 수행 할 수 있습니다.

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$"

내가 얻는 곳 :

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2

그리고 내가 할 때 :

readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

나는 얻다:

/dev/sdb

1

둘러보기를 사용할 수 있으면 허용되는 답변이 좋습니다. 그러나이 문제를 해결하는 또 다른 방법도 있습니다.

이 질문에 대해 널리 제안 된 정규식을 보면 :

.*[^a]$

우리는 그것이 거의 효과 가 있음을 알게 될 것입니다 . 빈 문자열을 허용하지 않으므로 약간 불편할 수 있습니다. 그러나 이것은 한 문자 만 처리 할 때 사소한 문제입니다. 그러나 "abc"와 같이 전체 문자열을 제외하려면 다음을 수행하십시오.

.*[^a][^b][^c]$

하지 않습니다. 예를 들어 ac를 허용하지 않습니다.

이 문제에 대한 쉬운 해결책이 있습니다. 우리는 간단히 말할 수 있습니다.

.{,2}$|.*[^a][^b][^c]$

또는보다 일반화 된 버전 :

.{,n-1}$|.*[^firstchar][^secondchar]$ 여기서 n은 (대한 금지하고자하는 문자열의 길이 abc는 3입니다), 그리고 firstchar, secondchar... 처음입니다, 당신의 문자열의 두 번째 ... n 번째 문자 (위해 abc가 될 것입니다 a, 다음 b, 다음 c).

이것은 우리가 금지하지 않은 텍스트보다 짧은 문자열이 정의에 의해이 텍스트를 포함 할 수 없다는 간단한 관찰에서 비롯됩니다. 따라서 더 짧은 것 ( "ab"는 "abc"가 아님)이나 끝이 없어도 받아 들일 수있을만큼 긴 것을 받아 들일 수 있습니다.

.jpg가 아닌 모든 파일을 삭제하는 find 예제는 다음과 같습니다.

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete


.{,2}$|.*[^a][^b][^c]$일치하지 않는ccc
psalaets

0

---로 끝나는 것이 일치 아무것도 .*a$당신이 정규식과 일치 때, 조건을 부정 또는 대안 당신은 또한 할 수 있는 수단 아무것도.*[^a]$[^a]not a


0

사용 중이 grep거나 sed구문이 약간 다릅니다. 순차 [^a][^b]방법은 여기서 작동하지 않습니다.

balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n'
jd8a
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a]$"
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^b]$"
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^c]$"
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c]$"
jd8a
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c^a]$"

FWIW, Regex101 에서 동일한 결과를 찾았습니다. . JavaScript 구문이라고 생각합니다.

나쁨 : https://regex101.com/r/MJGAmX/2
좋음 : https://regex101.com/r/LzrIBu/2

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