2016-09-05 2 views
-1

perl의 정규식 패턴이 대소 문자를 구분하는 문자열과 정확하게 일치하지만 대문자와 다른 문자열은 일치하지 않습니다. 첫 번째 행이 국가 이름이고 다른 행이 해당 국가의 약어 또는 다른 일반적인 철자 인 CSV 파일을 파싱합니다.대/소문자를 구별하지 않는 정규식 일치가 perl에서 작동하지 않습니다.

예 : CSV의 1 열은 미국, 미국, 미국, 미국입니다. 열 2는 멕시코, MX, MEX입니다. 내가 약어/철자 및보고의 배열을 통해 갈거야 여기

my $string = "Mex, MEX, USA, usa, US, MX, CAN, Canada"; 

open(my $fh, '<', $filename) or die "Can't open $filename: $!"; 

$line = <$fh>; 
@rowStrings = split("\r", $line); 

#make rows strings into arrays 
foreach my $i (0..$#rowStrings){ 
    $rows[$i] = [split(",",$rowStrings[$i])]; 
} 


my $columnCount = values scalar $rows[0]; 

print "column count: $columnCount \n"; 

#create array for each column from CSV 
foreach my $column (0..$columnCount){ 
    foreach my $row (0..$#rows){ 
     $columns[$column][$row] = $rows[$row][$column]; 
     if ($columns[$column][$row]) { 
     } 
    } 

} 

: 여기

는 전체 코드 ::

#!/usr/bin/perl 

use strict; 
use warnings; 
use Data::Dumper qw(Dumper); 

my $filename = 'countrycodes.csv'; 
my $line; 
my @rowStrings; 
my @rows; 
my @columns; 

이 내가 코드를 테스트하기 위해 사용하고있는 문자열입니다 일치합니다. 배열에서 약어를 검색하고 CSV 파일 ($ head)의 헤더/국가 이름으로 바꿉니다.

for my $col (0..$#columns-1){ 
    my $head = $columns[$col][0]; 
    for my $ro (1..$#rows){ 
     if ($columns[$col][$ro]){ 
      $string =~ s/\s$columns[$col][$ro],/ $head,/i; 
      print $string . "\n"; 
     } 
    } 

} 

이 최종 결과로 터미널 출력 : 그래서

Mex, Mexico, United States, usa, United States, Mexico, Canada, Canada 

당신은, MEX에도 불구하고, 멕스를 그게를 검색 용어이기 때문에 제대로 일치하는 것이 아니라 볼 수/i 수정자를 사용하고 있습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

편집 : 미국 일치하는, 미국에서 일치하지 않는다.

참고로 정규식 패턴은 $string =~ s/\s$columns[$col][$ro],/ $head,/i

당신을 감사합니다!

+0

'$ columns [$ col] [$ ro]'를 출력하여 일치하는 항목을 확인하지 않는 이유는 무엇입니까? – xxfelixxx

+0

처음에 그것을 인쇄하고있었습니다. 나는 그것이 CSV 필드의 정확한 철자와 일치하고 있지만, 다른 경우는 그렇지 않다는 것을 알고 있습니다. – chuckieDub

+0

'Text :: CSV;를 사용합니다. – Robert

답변

0

문제는 내가 한 번 의미하는 "G"연산자를 포함하지 않았다이었다 그것은 국가 이름 대안의 한 인스턴스를 발견, 다른 사람을 찾고 중지되었습니다.

$string =~ s/\s$columns[$col][$ro],/ $head,/i$string =~ s/\s$columns[$col][$ro],/ $head,/ig으로 변경하면 일치가 정확합니다.

0

내가하는 일을 완전히 이해하지는 못했지만 어쩌면이게 도움이 될 것입니다. 정규 표현식의 \ s는 공백과 일치하려고하지만 공백 부재와 일치하지 않습니다. "Mex"는 줄의 시작 부분에 있기 때문에 앞에는 공백이 없습니다. 실험으로 "Mex"를 줄의 다른 위치로 이동해보십시오.

+0

당신의 요점을 봅니다. 미국/미국은 어떨까요? – chuckieDub

0

CSV를 구문 분석하는 것이 문제가 아닌 것 같습니다. (나는 아직도 그것에 대해 Text::CSV을 권하고 싶다.)

당신은 당신의 언어와 대체물이 배열에 있다고 가정하고, alternatives-with-alternatives-arrays의 배열을 가지고 있다고 가정하면, 단지 입력을 비교할 수있다. 당신은 아마 앞과 뒤 부분의 공백을 제거하고, 대소 문자를 구분 비교,하지만 당신은 그것에 대해 정규식이 필요하지 않습니다해야합니다

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

my @countries = ( 
    ['United States of America', 'US', 'USA', 'US of A', 'United States'], 
    ['Mexico', 'MX', 'Mex'], 
); 

my @input = ('US ', ' mx ', ' Mexico', ' us of a'); 

foreach my $input (@input) { 
    $input =~ s/^\s+//; 
    $input =~ s/\s+$//; 
    my $found = 0; 
    foreach my $country (@countries) { 
     foreach my $alternative (@$country) { 
      if (lc($input) eq lc($alternative)) { 
       print "$input is ${$country}[0]\n"; 
       $found = 1; 
      } 
     } 
    } 
    print "did not find $input\n" unless($found); 
} 
+0

이 CSV에는 해당 문자가 포함될 수있는 사람들 이름이 포함되어 있기 때문에 대안을 둘러싼 모든 것을 제거 할 수 없습니다. – chuckieDub

+0

lc는 괜찮 으면서 Mex와 Usa를 생략하겠습니까? – chuckieDub