$ variable과 $ {variable} 사이의 정규 표현식에서 변수를 전달할 때 Perl의 차이는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/810876

문제

Perl로 작성된 Clearcase 트리거를 검토하고 있습니다. 나는 일부 정규 표현에서 변수가 곱슬 곱슬 한 괄호 안에있는 이름으로 변수가 전달된다는 것을 알았습니다.

예를 들어 트리거에 다음 코드 줄이 있습니다.

if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&
        $baseline !~ /^${project_root}_$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/)

$component, $phase, $automateddigit, $project_root 모든 변수입니다.

왜 일부는 통과합니까? $variable 그리고 다른 사람은 그대로 통과했습니다 ${variable} 정규 표현에서?

그들이 초기화되는 방식에서 나옵니까?

다음은 코드 라인이 초기화됩니다.

($project = $ENV{CLEARCASE_PROJECT}) =~ s/\@.*$//;
($component = $ENV{CLEARCASE_COMPONENT}) =~ s/\@.*$//;

($project_root, $phase) = ($project =~ /^(.*)_(R\d+.*)$/);

exit(0) if (! $phase);

$phase .= ".0" if ($phase =~ /^R\d+$/);

$automateddigit = '';

$istream = `cleartool desc -fmt "%[istream]p" project:$ENV{CLEARCASE_PROJECT}`;

$componentlist = `cleartool desc -fmt "%[components]Cp" stream:$ENV{CLEARCASE_STREAM}`;
$componentsnbr = split(',', $componentlist);

if ($componentsnbr > 1) {
    $automateddigit .= '\\.\\d+';
}
도움이 되었습니까?

해결책

변수를 $ {name}로 전달하면 변수 이름의 끝이 있고 인용 된 문자열의 나머지 부분이 시작되는 경우 명시 적으로 구분됩니다. 예를 들어, 코드에서 :

if ($baseline !~ /^${component}_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&

없이 {} 구분자 :

if ($baseline !~ /^$component_(|.*_)$phase\.\d+(|[a-z]|-\d+|${automateddigit})$/ &&

변수 $ 구성 요소 (어느 쪽이든 참조 할 수 있음) 정규 표현식의 후행 밑줄로 인해 $ component_로 잘못 해석됩니다.

다른 팁

첫째, 이것을 문자열 보간이라고합니다. 이 경우 사용하는 한 가지 이유 중 하나는 $ project_root가 $ project_root_로 해석되는 것을 방지하기 때문입니다 (후행 밑줄에 주목하십시오). 변수 이름을 명시 적으로 만들어내는 대신보다 복잡한 보간 규칙에 남겨 두는 대신 명시 적입니다.

보간에 대한 자세한 내용은 Perldata를 참조하고 정규 표현 연산자 내에서 보간 특성에 대한 Perlre 및 Perlop을 참조하십시오.

위에서 언급했듯이 변수 이름을 구분하는 것이 있습니다. 너무 많은 곱슬 버팀대는 이미 어려운 정규 표현을 더욱 어렵게 만듭니다. Curly Braces에는 자체 regexp 용도가 있습니다 (패턴 일치하는 횟수를 제한). regexp /x modifier를 사용하고 regexp를 다시 작성하는 것이 좋습니다.

if ($baseline !~ /^$component    # Start with $component
                   _             # then an underscore
                   (|.*_)        # Then nothing, or anything followed by an underscore
                   $phase        # ...
                   \.\d+         # ...
                   (|            # Then optionally:
                      [a-z]|       # lower alpha
                      -\d+|        # or ...
                      $automateddigit
                   )
                   $/x &&
    $baseline !~ /^$project_root
                   _
                   $phase
                   \.\d+
                   (|
                     [a-z]|
                     -\d+|
                     $automateddigit
                   )$/x)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top