2013-08-31 2 views
0

나는이 로그가 :펄 식 그룹

The Foo bar, and Bar foo needs to Foo 
The Bar of Bar foo Bar Foo Foo 
Bar bar The Bar of Foo other Foo Bar 

을 그리고 난 단지 Foo 등도 바되지 않은 단어를 선택 펄 expresion을 만들려고합니다. 그 결과 로그는 다음과 같아야합니다 :

^(Foo|Bar) 

그러나이 작동하지 않습니다

The bar, and foo needs to 
The of foo 
The of other 

나는이 하나 있습니다.

답변

3

정확하게 이해하면, Foo 또는 Bar이 아닌 모든 단어를 캡처 한 다음 어떻게 든 인쇄 할 수 있습니다.

/ 
    (?<!\S)   # match cannot be preceded by non-whitespace 
    (?!Foo|Bar)(\S+) # capture non-whitespace that is not Foo|Bar 
    (?!\S)    # match cannot be followed by non-whitespace 
/gx     # match globally and ignore whitespace in regex 

/x 즉, 그래서 주석을 사용 할 수 있습니다 단지가 :

보기보다 덜 복잡
/(?<!\S)(?!Foo|Bar)\S+(?!\S)/g 

, 여기에 주석 버전입니다 :이 그런 일을 할 수있는 하나 개의 방법이 될 것입니다 정규식 내부의 개행 문자.

이 정규식의 시작과 끝 부분은 경계 앵커입니다. 우리는 부분적으로 일치하지 않는지 확인하기 위해 이것을 사용합니다. 그것들은 부정적인 look-around 어설 션이고 다소 더 단순한 \b 단어 경계 어설 션을위한 대체 코드입니다. 문자열에 쉼표 문자가 있기 때문에 \b을 사용할 수 없습니다. 대신에 (?!\S)을 사용하는 이유는 둘 다 공백과 일치하지만 후자는 문자열의 시작/끝과 일치하지 않기 때문입니다.

우리는 부분 일치를 얻을 수 없다는 것을 확신 했으므로 이제 앵커 내부에서 간단한 미리보기를 사용하여 또 다른 부정적 미리보기 단정을 사용할 수 있습니다. 나는. (?!Foo|Bar). 일치하지 않으면 (\S+) 문자열을 캡처합니다. 이 $_ (입력)에서 문자열을 캡처 배열 참조 내부 @a 어레이에이를 밀어 우리 정규식을 사용

perl -nlwe 'push @a, [/(?<!\S)(?!Foo|Bar)(\S+)(?!\S)/g] }{ print "@$_" for @a' 
The Foo bar, and Bar foo needs to Foo 
The Bar of Bar foo Bar Foo Foo 
Bar bar The Bar of Foo other Foo Bar 
^Z 
The bar, and foo needs to 
The of foo 
bar The of other 

: 여기

는 I이 문제에 대해 생성 된 테스트 케이스이다. 입력이 끝난 후 (eskimo 연산자 }{ 다음) 보간 된 배열 참조를 인쇄하여 공백을 추가합니다. 이 경우 "@$_"join " ", @$_과 같습니다.

+2

+1 나는 그가 그걸 요구하고 있다고 믿는다. – ChicagoRedSox

+0

@ChicagoRedSox 당신은 그가 그 말을하도록 이끌어 낸 사람이었다. 그래서 당신은 +1했다. – TLP

3

당신은 문자열에서 값을 제거 하려는 경우, 대체 작동 것이다 : 마지막으로 "바"(소문자)이 여전히 있음을

my $str = <<EOS; 
    The Foo bar, and Bar foo needs to Foo 
    The Bar of Bar foo Bar Foo Foo 
    Bar bar The Bar of Foo other Foo Bar 
EOS 
$str =~ s/(?:Foo|Bar) ?//g; 
print $str; 

>>>The bar, and foo needs to 
    The of foo 
    bar The of other 

참고; 나는 그것이 귀하의 게시물에 실수라고 가정합니다.

+0

네거티브 형식의 정규 표현식 만 필요합니다. (Foo | Bar)와 비슷하지만 부정 구문을 사용합니다. Noot using! ~ – crsuarezf

+2

@ingcarlos - 그런 다음 질문을 수정하여 찾고있는 것이 무엇인지 실제로 설명하십시오. Foo 나 Bar가 아닌 문자열의 모든 단어와 일치하는 정규 표현식을 원한다고 말하는 것 같습니다. (이 경우 Perl의 질문이 아니라 PCRE의 일반적인 질문입니다.) – ChicagoRedSox

+0

대체품이 매력처럼 작동한다는 것도 알고 있지만 표현이 필요합니다. – crsuarezf