grep에서 작동하지 않는 올바른 정규식


13

나는이 정규식을 가지고있다 :

(?<=prefix).*$

문자열 "prefix"뒤에 오는 모든 문자를 반환하며 온라인 정규식 엔진 (예 : https://regex101.com ) 에서 제대로 작동합니다 . 문제는 bash에서 해당 정규 표현식을 사용할 때입니다.

grep '(?<=prefix).*$' <<< prefixSTRING

일치하지 않습니다. 그 정규식이 grep과 작동하지 않는 이유는 무엇입니까?


11
이것은 regex101이 JS, Perl / PHP 및 Python에 대해 POSIX 플레이버 선택기가 필요한 이유를 실제로 강조합니다. 내가 원하는 횟수를 셀 수 없습니다.
Jared Smith


또한 .*$일치는 한 문자가 아니라 줄 끝까지 (또는 문자열 끝까지) 모든 문자열과 일치합니다.
ilkkachu

답변:


38

올바른 정규 표현식을 정의한 것 같지만이 grep를 이해하기 위해 명령 행에 충분한 플래그를 설정하지 않았습니다 . 기본적으로 grepBRE를 지원하고 -E플래그 와 함께 ERE를 수행합니다. 가지고있는 것 (look-aheads)은 PCRE 정규 표현식에서만 사용할 수 있으며 GNU grep와 함께 -P플래그 만 지원됩니다 .

일치하는 부분 인쇄한다는 것을 알리기 위해 추가 플래그 를 추가 한 후 일치하는 문자열 추출해야한다고 가정합니다.prefix-ogrep

grep -oP '(?<=prefix).*$' <<< prefixSTRING

grep기본적으로 PCRE 라이브러리를 지원 하는 버전도 pcregrep있습니다.

pcregrep -o '(?<=prefix).*$' <<< prefixSTRING

다양한 정규식 맛에 대한 자세한 설명은이 멋진 Giles의 답변 과 각 기능을 구현하는 도구에 설명되어 있습니다


38

정규식은 여러 가지 맛으로 나옵니다. 당신이 보여주는 것은 Perl과 같은 정규 표현식 (PCRE, "Perl Compatible Regular Expression")입니다.

grepPOSIX 정규식을 수행합니다. 이들은 기본적인 정규 표현식 (BRE) 및 확장 정규식 (ERE, 경우 grep함께 사용되는 -E옵션). 시스템에 대한 매뉴얼 re_format또는 regex이와 유사한 매뉴얼 grep또는 방금 링크 한 POSIX 표준 텍스트를 참조하십시오.

GNU grep를 사용 grep하는 경우 GNU grep관련 -P옵션 과 함께 사용하면 Perl과 같은 정규식을 사용할 수 있습니다.

또한 줄의 하위 문자열이 아닌 기본적으로 grep반환 합니다. 다시 한 번, GNU (및 다른 구현)에서는 옵션을 사용하여 각 행에서 주어진 표현식과 일치하는 비트 만 가져올 수 있습니다 .grepgrep-o

모두 참고 -P하고 -o비표준 확장입니다 의 POSIX 사양grep .

GNU를 사용하지 않는다면 대신 문자열 과 줄 끝 사이의 비트를 얻는 데 grep사용할 수 있습니다 .sedprefix

sed -n 's/.*prefix\(.*\)/\1/p' file

이 작업은 sed주어진 대체를 적용 할 행만 인쇄하는 것입니다. 대체는 표현식 (BRE)과 일치하는 전체 행을 string 다음에 발생하는 부분으로 대체합니다 prefix.

prefix한 줄에 여러 인스턴스가 있는 경우 sed변형은 마지막 문자열 뒤에 문자열을 반환 하고 GNU grep변형은 첫 번째 문자열 뒤에 문자열을 반환합니다 (다른 인스턴스 포함 prefix).

sed솔루션은 모든 유닉스 계열 시스템에 이식 가능합니다.


6

다른 답변에서 언급했듯이 greplookbehinds와 함께 정규 표현식을 사용하지 마십시오 (기본적으로 GNU grep또는 다른 버전에서는 사용하지 않음).

당신이 찾아내는 경우에 자신이없는 GNU를 사용 grep하거나 pcregrep당신이 사용할 수있는, perl당신이있는 경우.

명령 행은 다음과 같습니다 perl.

perl -ne 'print if /(?<=prefix).*$/' <<< prefixSTRING

슬래시 사이에 원하는 정규식을 넣습니다. Perl을 사용함에 따라 Perl의 정규 표현식 플레이버가 사용 됩니다.


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