2012-05-02 2 views
4

이것은 바보 같은 질문입니다. 좀 더 복잡한 일이 필요하지만, 이제 그것을 간단하게하자음역 연산자에서 변수 사용

$i = quotemeta 'A'; 
$line =~ tr/a-z/$i-Z/; 

이 바보 대체이며,이 자본들에 소문자를 설정해야합니다,하지만 지금까지 내가 시도 작동하지 않습니다. 나는이 많은 혼란을 가져 볼 수 있도록

좋아, 실제 코드는 다음과 같아야합니다

$line =~ tr/A-Z/F-ZA-E/;

는 그것은 Caesers Chiper의 algorhytm해야합니다. 이것은 고정 된 수의 글자로 바꾸고 싶다면 잘 작동하지만 원하는만큼 많은 수의 글자를 바꿀 수 있도록 변수가 필요합니다. 하지만 배송하고 싶습니다. Thnx

P.S. 또한 s ///가 범위와 함께 작동하지 않는 이유는 무엇입니까?

답변

4

: 또한

$i = quotemeta 'A' 
eval("\$line =~ tr/a-z/$i-Z/;"); 
+1

''eval'마다 최상의 테스트'$ @ '가 있습니까? – tchrist

+0

네, 아마도 좋은 생각입니다. – happydave

4

tr///을 사용하면 변수가 아닌 리터럴 문자 만 사용할 수 있습니다. 따라서 tr/a-z/$i-Z/이 작동하지 않으면 tr/a-z/A-Z/을 사용해야합니다. perldoc perlop에서 tr///에 대한 자세한 내용을 보거나 보간이나 부족에 대한 설명을 찾을 수 있습니다.

문자열을 대문자로 바꾸려면 다른 방법이 있지만. uc 함수 또는 정규식 이스케이프 시퀀스 \U (대문자) 및 \L (소문자)을 사용할 수 있습니다. 예컨대 :

my $str = 'a'; 
my $uppercase = uc $str; 

정규식 : [a-z]이 사건에 의해 영향을받는 모든 문자를 포함 \p{CWU}를 작성해야한다는 지적 tchrist

my $str = 'abcdef'; 
$str =~ s/([a-z]+)/\U$1/; # $str is now 'ABCDEF' 

.

업데이트 :

동적 인코딩 기능의 어떤 종류를 만들려고하는 경우, 내가 인수를, 주변에 수동으로 문자를 이동 서브 루틴을 건의 할 것입니다.

sub foo { 
    my ($str, $num) = @_; # num is how many characters to shift the alphabet 
    my @in = 'A' .. 'Z'; 
    my @out = @in[$num .. $#in, 0 .. $num-1]; 
    my %out = map { $in[$_] => $out[$_] } 0 .. $#in; 
    $str =~ s#(.)# $out{$1} // $1 #eg; # if key does not exist, use org 
    return $str; 
} 

대소 문자를 구분하지만 대문자를 추가하여 문제를 해결할 수 있습니다.

+0

을, 당신은 매우 * * 대문자,'ucfirst'에 대한'uc'를 사용해야합니다 소문자는'lc', foldcase는 v5.16의'fc'이다. 불쾌한 깨진 ASCII 방식으로하지 마십시오. – tchrist

+0

@ tchrist 그리고 그게 어떤가? 이스케이프 시퀀스? 왜 그렇게 부러 졌습니까? – TLP

+0

당신은 나를 미워할 것입니다. 그러나 여러분은 정말로 $ str = ~ s/(\ p {CWU} +)/\ U $ 1/g'를 의미합니다. '[a-z]'를 보는 것은 정말로 post-ASCII 시대의 안티 패턴입니다. – tchrist

0

tr가 변수와 함께 작동하지 않습니다. 대신에 s /// (대체)를 사용하십시오.

+0

'a-z'와 같은 대체 문자를 어떻게 제안 하시겠습니까? 이것은 답이 아닙니다. – TLP

+0

예, s ///로 범위를 가져올 수 없습니다. 범위가 있고 tr 및 s가 아닌 다른 함수가 있습니까? – Zippie

+0

범위를 사용할 수 있습니다. 내 대답에 나타난 것처럼. 나의 요점은 Kenosis가 '\ U'로 어떻게 끝났는지를 지정하지 않았다는 것입니다. – TLP

2

귀하의 예는 불행히도 좋지 않습니다. tr 연산자는 변수 보간을 허용하지 않습니다 (둘 중 하나에서). 실제로 tr을 사용하는 경우 eval에 있지 않으면 운이 없으므로 권장하지 않습니다. tr을 사용하지 않는 경우 실제 코드를 표시하여 진행 상황을 확인하고 더 많은 제안을 제공하십시오.

UPDATE

방법에 대해?때문에 끔찍한 성능 저하하지 여전히 사실이라면 모르겠지만, 한 번 $&이었다 한 번에 모든 피해야하는시

my %map; 
@map{'A'..'Z'} = ('F'..'Z','A'..'E'); 
s/[A-Z]/$map{$&}/g; 

. 당신은 그렇게 쉽게 충분히 수행 할 수 있습니다 당신이 정말로 그럴 필요하면, 당신은 평가 사용할 수

s/([A-Z])/$map{$1}/g; 
+3

그만. 이 목적을 위해'eval'을 사용하는 것에 대해 아무런 권고가 없습니다. 쳇. – tchrist

+0

질문을 편집하여 더 명확해질 수 있습니다. – Zippie

+0

@tchrist 아마도 과잉이라고 할 수 있습니다. 나는 해킹하기 위해 eval에 의존하는 것보다 적절한 기술을 배우는 것이 더 낫다고 주장 할 것이다. – TLP