将tr与数组一起使用

时间:2019-06-11 12:02:33

标签: perl tr

我正在尝试使用tr函数指定两个数组,作为to和from集合。翻译似乎不起作用,或者我无法正确理解。 我是perl的新手,所以如果我做错了事,请告诉我

我将数组加载为(我知道这部分工作了):

open my $fh,'<',"${main_dir}/char_convert" or die "Cannot open allowed conversion file";
my @from_set;
my @to_set;
my @conversion;
while (my $lines = <$fh>) {
  @conversion = split(" ",$lines);
  push @from_set,$conversion[0];
  push @to_set,$conversion[1];
}

#The variable $line holds the data I want converted:
my $statement;
my $result;
$statement = "tr\@from_set\@to_set\$line;"; # Setup the tr command
$result = eval($statement); # perform the conversion
print "$line\n";

结果与输入的数据相同。似乎没有进行任何转换。 我在做什么错了?

数据的示例部分是“PICAÑA”。 转换文件中的行是“ÑN” 所以我希望退出“ PICANA”,但是我得到了原始数据

感谢您的光临

4 个答案:

答案 0 :(得分:6)

我假设您选择sess = tf.Session() cost = sess.run(cost,feed_dict={z:logits,y:labels}) sess.close() print(cost) ,因为它比if (innerItemChild.FirstOrDefault()?.Type == JTokenType.String)快。如果是这样,每次进行翻译时都使用tr///会达到目的。如果您只使用一次s///,但是执行多次音译,那么它将更快。

除了可以多次使用已编译的eval,以下还修复了Perl语法错误和code injection错误:

eval

另一方面,如果您只执行一次音译,那么您将使生活变得更加复杂,并通过使用tr///来减慢程序速度。请改用my $from_set = join '', @from_set; my $to_set = join '', @to_set; my $tr = eval("sub { \$_[0] =~ tr/\Q$from_set\E/\Q$to_set\E/r }") or die($@); my $output = $tr->($input);

tr///

答案 1 :(得分:3)

您的$statement有点过头了,因为通常的格式是$line =~ tr/a/b/,对吧?所以应该像这样:

my $statement = "\$line =~ tr/\Q@from_set\E/\Q@to_set\E/;"

在评估期间,$line应该保留为变量,因此它会以\$line的形式转义。 @from_set@to_set的内容应内插到$statement中,因此在不使用\的情况下给出它们。

答案 2 :(得分:2)

这里有一些问题。它们主要围绕# Get the positives depending on the threshold you chose threshold = x preds_proba = GB.predict_proba(df_test[x]) predictions_ex = [1 if x[1]>threshold else 0 for x in preds_proba] # We retrieve the indexes of the predicted positive values test_pos = [i for i, x in enumerate(predictions_ex) if x == 1] # We get the indexes of positives test_true_pos = y_test[y_test == 0].index # We can now compute the number of FP and TP true_positives = [x for x in index_pos if x in index_true_pos] false_postives = [x for x in index_pos if x not in index_true_pos] 语句的语法。应该是这样的:

tr/../../

您在错误的位置放置了$line =~ tr/CHARS/CHARS/; ,并且您使用的是反斜杠而不是正斜杠(您可以在$line语句中使用正斜杠作为定界符,但请记住,它们具有特殊的含义意思是用双引号引起来的字符串。)

这似乎可以满足您的要求(为了方便测试,我已改用内部tr/.../.../文件句柄。

DATA

很明显,我不知道您正在处理的是哪些字符,但看起来您可能会发现Text::Unidecode有用。

更新:还有一点需要指出,#!/usr/bin/perl use strict; use warnings; use feature 'say'; use utf8; my @from; my @to; while (<DATA>) { chomp; my @conv = split; push @from, $conv[0]; push @to, $conv[1]; } my $line = 'PICAÑA'; my $statement = "\$line =~ tr/@from/@to/"; eval $statement; say $line; __DATA__ Ñ N Ê E 语句仍然不太正确(尽管它可以工作)。如果您打印tr/.../.../,则会看到以下信息:

$statement

多余的空间来自以下事实:当在双引号字符串中进行插值时,Perl在数组元素之间放置一个空格。如果您愿意,可以通过将$line =~ tr/Ñ Ê/N E/ 设置为空字符串来解决此问题。

更新2:

再考虑一下,我想我根本不会使用数组。为什么不使用标量呢?

$"

答案 3 :(得分:2)

在Perl Mongers中,如果您想要防止注入斜线的安全性,则应使用像这样的quotemeta或使用@ikegami解决方案:

eval sprintf "tr/%s/%s/", map quotemeta, $oldlist, $newlist;

https://www.perlmonks.org/?node_id=445971