2011-04-22 4 views
1

알아? 연산자는 "욕심이 많지 않은"모드를 사용할 수 있지만 문제가 발생하여 주변을 둘러 볼 수 없습니다. 이 같은 문자열을 고려최단 시합 문제

my $str = '<a>sdkhfdfojABCasjklhd</a><a>klashsdjDEFasl;jjf</a><a>askldhsfGHIasfklhss</a>'; 

가 열고 태그 <a></a>을 닫는 키 ABC, DEF와 GHI가 있지만, 다른 임의의 텍스트에 둘러싸여 있습니다. 예를 들어 <a>klashsdjDEFasl;jjf</a><b>TEST</b>으로 바꾸고 싶습니다. . 심지어 비 욕심 사업자와

$str =~ s/<a>.*?DEF.*?<\/a>/<b>TEST><\/b>/; 

*? 이것이 내가하고 싶은 일을하지 않습니다 그러나, 나는 이런 식으로 뭔가가있다. 왜 처음에는 <a>이 문자열의 첫 번째 일치 항목과 일치하고 DEF까지 일치하는지 확인한 다음 가장 가까운 닫는 부분 인 </a>과 일치하기 때문에 이유가 무엇인지 알지 못합니다. 그러나 내가 원하는 것은 가까운 개구부 <a>을 일치시키고 </a>을 닫는 것이 "방어"하는 방법입니다. 나는이 결과를 얻으려면 뭔가를 찾고 있어요 같은 경우

<a>TEST</b><a>askldhsfGHIasfklhss</a> 

:, 내가 여기에 HTML을 구문 분석을 시도하고 있지 않다 그런데

<a>sdkhfdfojABCasjklhd</a><b>TEST</b><a>askldhsfGHIasfklhss</a> 

을 나는, 그래서 현재, 나는 결과로이를 얻을 수 이것을 할 수있는 모듈이 있다는 것을 알고, 나는 이것이 어떻게 행해질 수 있는지를 묻는 것입니다.

감사 문제도 아닌 욕심 일치, 펄 여전히 문자열의 왼쪽 가능한 지점에서 시작하는 경기를 찾기 위해 노력하고 있다는 점이다 에릭 페르

답변

6
$str =~ s/(.*)<a>.*?DEF.*?<\/a>/$1<b>TEST><\/b>/; 

. .*?<a> 또는 </a>과 일치 할 수 있으므로 줄에 처음으로 항상 <a>을 찾습니다. 처음에 욕심 (.*) 추가

마지막 가능한 라인에 <a> 일치 (첫번째 .* 전체 라인을 잡고, 다음 백 트럭 때문에 일치가 발견 될 때까지) 발견됩니다.

주의 사항 : 가장 가까운 일치 항목을 먼저 찾기 때문에 /g 수정 자와 함께이 기술을 사용할 수 없습니다. 추가 경기는 $1 안에 있으며 /g은 이전 경기가 끝난 곳에서 검색을 재개하므로 찾을 수 없습니다. 말한다 대신 점의

1 while $str =~ s/(.*)<a>.*?DEF.*?<\/a>/$1<b>TEST><\/b>/; 
+0

감사합니다. 이것은 내가 찾고있는 것입니다. –

2

: 는 "이 아닌 모든 문자와 일치 : 당신이 정말 밝히는 필요한 사용 ,"모든 문자와 일치 "대신 같은 루프를 사용해야 할 것 </a>의 시작은 "입니다.이것은 이런 식으로 번역 : 기본적으로

$str =~ s/<a>(?:(?!<\/a>).)*DEF(?:(?!<\/a>).)*<\/a>/<b>TEST><\/b>/; 
+0

@ysth : 이스케이프를 주셔서 감사합니다 ... – ridgerunner

0
#!/usr/bin/perl 
use warnings; 
use strict; 

my $str = '<a>sdkhfdfojABCasjklhd</a><a>klashsdjDEFasl;jjf</a><a>askldhsfGHIasfklhss</a>'; 

my @collections = $str =~ /<a>.*?(ABC|DEF|GHI).*?<\/a>/g; 

print join ", ", @collections; 
+0

문자열에서 ' ...'의 모든 일치와 일치하도록 정규식을 변경하면됩니다. 그것은 원래의 문제를 해결하지 못합니다. 원래 문제는 이러한 그룹 중 하나와 일치하는 것입니다. – cjm

+0

아, 네 말이 맞아. @cjm – SymKat

0
s{ 
    <a> 
    (?: (?! </a>) .)* 
    DEF 
    (?: (?! </a>) .)* 
    </a> 
}{<b>TEST</b>}x; 

,

(?: (?! PAT) .) 

정규식 패턴 대신에 문자를

[^CHARS] 

하는 것과 동일합니다.