이 출력을 얻으려면 어떻게 해야 합니까?
Found value: This order was placed for QT3000! OK?
또는
Found value: This order was placed for QT300
또는
Found value: 0
line.txt
및 다음과 같이 사용하십시오 pattern.txt
.
[nsaunders@rolly regex]$
[nsaunders@rolly regex]$ grep -e -f pattern.txt line.txt
[nsaunders@rolly regex]$
[nsaunders@rolly regex]$ cat pattern.txt
(.*)(\\d+)(.*)
[nsaunders@rolly regex]$
[nsaunders@rolly regex]$ cat line.txt
This order was placed for QT3000! OK?
[nsaunders@rolly regex]$
사용무엇비슷한m.group(0)
하나 에서지도 시간정규 표현식에 대해.
어쩌면 grep
그런 일은 없을지도 모르지개념처럼:
Groups and capturing
Group number
Capturing groups are numbered by counting their opening parentheses from left to right. In the expression ((A)(B(C))), for example, there are four such groups:
1 ((A)(B(C)))
2 (A)
3 (B(C))
4 (C)
Group zero always stands for the entire expression.
Capturing groups are so named because, during a match, each subsequence of the input sequence that matches such a group is saved. The captured subsequence may be used later in the expression, via a back reference, and may also be retrieved from the matcher once the match operation is complete.
답변1
가정된 패턴 pattern.txt
은 다음과 같습니다.
(.*)(\d+)(.*)
글쎄요, GNU와 함께 사용하는 것은 grep
문제가 될 것입니다
grep -E -f pattern.txt line.txt
즉, 질문의 데이터를 바탕으로 line.txt
에 나열된 확장 정규 표현식과 일치하는 행을 검색하면 다음이 생성됩니다.pattern.txt
This order was placed for QT3000! OK?
명령의 문제점은 -e -f
. -e
옵션을 사용하여 "다음 인수는 표현식입니다"라고 명시적으로 말하는 것입니다. 이는 -e -f
"사용할 정규 표현식은 다음과 같습니다"로 해석됩니다 -f
. 그런 다음 이를 적용하여 명령줄에 언급된 두 파일에서 일치하는 항목을 검색합니다.
두 번째 문제는 \\d
파일에 있는데 pattern.txt
, 백슬래시 뒤에 문자가 오는 것과 일치하는데 d
, 이는 리터럴 문자열입니다 \d
.
이 모델에는 몇 가지 다른 "문제"가 있습니다. 먼저 비표준 표현식을 사용하여 숫자를 일치시킵니다 \d
. [[:digit:]]
또는 범위 [0-9]
(POSIX 표준 로케일) 로 작성하는 것이 더 좋습니다 . 항상 자동으로 고정되는 파일 이름 와일드카드 패턴과 달리 정규식은 하위 문자열과 일치하므로 .*
패턴이 필요하지 않습니다. 다시 말하지만, 괄호는 패턴에서 아무런 용도로 사용되지 않으므로 전혀 필요하지 않습니다. 단일 숫자가 이전 표현식과 일치하므로 필요 하지 않습니다 +
(단일 숫자는 "하나 이상의 숫자"를 의미함).
이는 (적어도) 하나의 숫자를 포함하는 모든 줄을 추출하려면 패턴 [[:digit:]]
또는 를 사용할 수 있거나 추가 수정 없이 GNU에서 Perl과 같은 표현식을 계속 사용하려는 경우를 [0-9]
의미 합니다. 이들 간의 차이점은 다음을 참조하세요.\d
grep
[0-9], [[:digit:]] 및 \d의 차이점.
질문에 표시된 세 가지 다른 출력을 얻으려면 sed
대신 를 사용하십시오 grep
. 이것을 사용하려는 이유 sed
는 grep
일치하는 줄(또는 단어)만 인쇄할 수 있고 일치하는 데이터를 실제로 수정할 수 없기 때문입니다.
Found value:
숫자가 포함된 줄 앞에 삽입하고 해당 줄을 인쇄합니다.$ sed -n '/[[:digit:]]/s/^/Found value: /p' line.txt Found value: This order was placed for QT3000! OK?
Found value:
숫자가 포함된 줄 앞에 삽입하고 찾은 세 번째 숫자가 끝날 때까지 해당 줄을 인쇄합니다.최대세 번째 숫자; 줄의 첫 번째 숫자 하위 문자열에 연속 숫자가 더 적으면 끝에 더 적은 숫자가 출력될 수 있습니다.$ sed -n '/[[:digit:]]/s/\([^[:digit:]]*[[:digit:]]\{1,3\}\).*/Found value: \1/p' line.txt Found value: This order was placed for QT300
Found value:
숫자가 포함된 줄 앞에 삽입하고 줄의 마지막 번호를 인쇄합니다.$ sed -n '/[[:digit:]]/s/.*\([[:digit:]]\).*/Found value: \1/p' line.txt Found value: 0
사용한 것과 동등한 정규식을 사용하면 일치하는 텍스트 비트를 확인할 수 있습니다.
$ sed 's/\(.*\)\([[:digit:]]\{1,\}\)\(.*\)/(\1)(\2)(\3)/' line.txt
(This order was placed for QT300)(0)(! OK?)
이전 숫자 는 탐욕적 이므로 \2
줄의 마지막 숫자만 일치합니다 ..*
답변2
grep에서는 캡처 그룹에 액세스할 수 없을 것 같지만 Perl에서는 가능합니다.
$ echo 'foo123bar' | re='(.*)(\d+)(.*)' \
perl -lne 'if (m/$ENV{re}/) { printf "Found value: %s\n", $_ for @{^CAPTURE} }'
Found value: foo12
Found value: 3
Found value: bar
-n
기본적으로 입력 줄(implicit로 읽음 )을 env 변수 re
(패턴을 전달하기 위해 명령줄에 설정) 에 있는 내용과 일치시키고 @{^CAPTURE}
일치하는 경우 접두사와 함께 캡처된 모든 텍스트(배열에서)를 인쇄한다고 말합니다 .
답변3
자바에서:
jshell> /reset
| Resetting state.
jshell> /open grep.jsh
This order was placed for QT3000! OK?
This order was placed for QT300
0
jshell> /list
1 : import static java.lang.System.out;
2 : String text = "This order was placed for QT3000! OK?";
3 : String patternString1 = "(.*)(\\d+)(.*)";
4 : Pattern pattern = Pattern.compile(patternString1);
5 : Matcher matcher = pattern.matcher(text);
6 : matcher.find()
7 : out.println(matcher.group(0))
8 : out.println(matcher.group(1))
9 : out.println(matcher.group(2))
jshell>
나는 사용에 더 관심이 있었지만 실제로는 그렇지 않다는 group
것을 깨닫지 못했습니다 .grep
하다저것.