[regex] grep에서 욕심없는 매치를하는 방법?

가장 짧은 일치 항목을 그 리핑하고 패턴은 다음과 같아야합니다.

<car ... model=BMW ...>
...
...
...
</car>

…는 모든 문자를 의미하며 입력은 여러 줄입니다.



답변

당신은 욕심이없는 (또는 게으른) 성냥을 찾고 있습니다. 정규 표현식에서 욕심없는 일치를 얻으려면 ?수량화 후 수정자를 사용해야합니다 . 예를 들어, 당신은 변경할 수 있습니다 .*.*?.

기본적 grep으로 욕심없는 수정자를 지원하지 않지만 grep -PPerl 구문을 사용하는 데 사용할 수 있습니다 .


답변

실제로 .*?유일하게 작동합니다 perl. 동등한 grep 확장 regexp 구문이 무엇인지 잘 모르겠습니다. 다행히도 grep과 함께 perl 구문을 사용할 수 있으므로 grep -P작동하지만 작동하지 않는 grep -E것과 동일 egrep합니다 (욕심이 많음).

참조 : http://blog.vinceliu.com/2008/02/non-greedy-regular-expression-matching.html


답변

이 스레드에서 물건을 시험해 본 후에 작동하는 내 grep :

echo "hi how are you " | grep -shoP ".*? "

각 줄에 공백을 추가하십시오.

(마인은 한 줄씩 검색하여 단어를 뱉어 냈습니다)


답변

grep

욕심없는 일치의 grep경우 부정 문자 클래스를 사용할 수 있습니다. 즉, 와일드 카드를 피하십시오.

예를 들어, 페이지 컨텐츠에서 jpeg 파일에 대한 모든 링크를 가져 오려면 다음을 사용하십시오.

grep -o '"[^" ]\+.jpg"'

여러 줄을 처리하려면 xargs먼저 입력을 파이프로 연결하십시오 . 성능을 위해을 사용하십시오 ripgrep.


답변

짧은 대답은 다음 정규식을 사용하는 것입니다.

(?s)<car .*? model=BMW .*?>.*?</car>
  • (? s)-여러 줄에 걸쳐 일치합니다.
  • . *? -게으른 방식으로 모든 문자와 일치합니다 (최소 일치)

좀 더 복잡한 대답은 다음과 같습니다.

(?s)<([a-z\-_0-9]+?) .*? model=BMW .*?>.*?</\1>

다음 텍스트에서 car1과 car2를 일치시킬 수 있습니다.

<car1 ... model=BMW ...>
...
...
...
</car1>
<car2 ... model=BMW ...>
...
...
...
</car2>
  • (..)는 캡처 그룹을 나타냅니다
  • 이 문맥에서 \ 1은 그룹 번호 1을 캡처하여 가장 최근에 일치 한 것과 동일한 텍스트와 일치합니다.

답변

늦어서 죄송합니다. 2020 년에는 시청자에게 효과가있을 수 있습니다.

따라서 같은 줄이 있다고 가정하십시오 "Hello my name is Jello". 이제 사이에 임의의 수의 문자가있는로 시작 'H'하고 끝나는 단어를 찾으려고합니다 'o'. 그리고 우리는 단어 만 원하는 줄을 원하지 않습니다. 이를 위해 다음 표현식을 사용할 수 있습니다.

grep "H[^ ]*o" file

이것은 모든 단어를 반환합니다. 이것이 작동하는 방식은 다음과 같습니다. 공백 문자 대신 모든 문자를 허용하므로 같은 줄에서 여러 단어를 피할 수 있습니다.

이제 공백 문자를 원하는 다른 문자로 바꿀 수 있습니다. 초기 줄이라고 가정하면 "Hello-my-name-is-Jello"표현식을 사용하여 단어를 얻을 수 있습니다.

grep "H[^-]*o" file


답변

나는 그 게시물이 약간 죽은 것을 알고 있지만 이것이 효과가 있음을 알았습니다. 출력에서 정리와 정리를 모두 제거했습니다.

> grep -v -e 'clean\-\?up'
> grep --version grep (GNU grep) 2.20