나는 여전히 펄을 배우기 때문에 분명한 질문입니다. 괄호로 묶지 않은 텍스트를 찾는 방법이 있습니까? 예를 들어 foo를 검색하면 두 번째 줄만 일치합니다. ("일치 찾을 때까지 문자를 스킵")일치하는 텍스트가 괄호로 묶이지 않음
(bar foo bar)
bar foo (
bar foo
(bar) (foo)
)
나는 여전히 펄을 배우기 때문에 분명한 질문입니다. 괄호로 묶지 않은 텍스트를 찾는 방법이 있습니까? 예를 들어 foo를 검색하면 두 번째 줄만 일치합니다. ("일치 찾을 때까지 문자를 스킵")일치하는 텍스트가 괄호로 묶이지 않음
(bar foo bar)
bar foo (
bar foo
(bar) (foo)
)
이것은 "명백한"것은 아닙니다. 반대로. 복잡한 패턴에 대해 "일치하지 않는다"라고 말하는 직접적인 방법은 없습니다 (문자 수준에서 좋은 지원이 있습니다, [^a]
, \S
등). 정규 표현식은 먼저 일치하는 것에 관한 것이지 일치하지 않는 것에 관한 것이 아닙니다.
하나의 방법은 해당 중첩 된 구분 기호를 일치시키고 그 이외의 모든 것을 얻는 것입니다.
중첩 된 구분 기호를 찾는 좋은 도구는 핵심 모듈 Text::Balanced입니다. 일치하는 부분은 일치하기 전의 부분 문자열과 일치 이후의 부분 문자열을 제공 할 수 있습니다.
use warnings;
use strict;
use feature 'say';
use Text::Balanced qw(extract_bracketed);
my $text = <<'END';
(bar foo bar)
bar foo (
bar foo
(bar) (foo)
)
END
my ($match, $before);
my $remainder = $text;
while (1) {
($match, $remainder, $before) = extract_bracketed($remainder, '(', '[^(]*');
print $before // $remainder;
last if not defined $match;
}
extract_bracketed
반환 경기, 경기 전에 하위 문자열 나머지 ($remainder
) 및 하위 문자열 ($before
); 그래서 우리는 나머지 부분에서 일치를 유지합니다.
취한 this post 여기에는 더 자세한 정보와 다른 방법이 있으며 Regexp::Common을 사용합니다.
이 모듈에 대해 알지 못했습니다. 감사! 그러나'$ text' 또는'$ lead' 내부에서 일치 할 때 줄 번호를 찾는 것이 어렵다는 것을 알고 있습니다. 한가지 방법은'$ match'에서 개행 문자의 수를 세는 것입니다. 그러나 더 좋은 방법이 있습니까? – Tohiko
@Tohiko 환영합니다. 근원에있는 숯/선이 무엇인지 발견하고 싶습니까? '$ lead' (또는'$ text', 그것이 고갈됨에 따라)에서'\ n'을 세기는 것은 소스에있는 행을 알려주지 않습니다. 나는 그것을 들여다 볼 것이다. – zdim
@Tohiko'$ lead'를'$ before'로,'$ text'를'$ remainder'로 변경했음을 참고하십시오. – zdim
정규식 패턴 암시 최고의 \G(?s:.)*?
있습니다. 다음은 중첩 된 괄호를 건너 뛸 문자로 간주하기 위해 해당 정의를 확장합니다.
while (
$string =~ m{
\G (?&MEGA_DOT)*?
(foo)
(?(DEFINE)
(?<MEGA_DOT> [^()] | \((?&MEGA_DOT)*+ \))
)
}xg
) {
say "Found a match at pos $-[1].";
}
부정적 예측을 사용하고 있습니까? – Boschko