Ввод данных в процесс perl автоматически декодирует строку в кодировке URL

я использую proc_open передать некоторый текст в Perl-скрипт для более быстрой обработки. Текст содержит строки в кодировке URL, а также буквенные пробелы. Когда в необработанном тексте появляется пространство с кодировкой URL, кажется, что к моменту достижения сценария perl оно декодируется в буквальное пространство. В сценарии perl я полагаюсь на расположение буквенных пространств, поэтому эти нежелательные пробелы портят мой вывод.

Почему это происходит, и есть ли способ предотвратить это?

Соответствующий фрагмент кода:

$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
);
$cmd = "perl script.pl";
$process = proc_open($cmd, $descriptorspec, $pipes);
$output = "";

if (is_resource($process)) {
fwrite($pipes[0], $raw_string);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$output .= fgets($pipes[1]);
}
fclose($pipes[1]);
proc_close($process);
}

и строка ввода необработанного текста выглядит примерно так:

key url\tvalue1\tvalue2\tvalue3

Я мог бы избежать этой проблемы, преобразовав форматирование моих входных данных, но по разным причинам это нежелательно и обходит, а не решает ключевую проблему.

Кроме того, я знаю, что проблема возникает где-то между сценарием php и сценарием perl, потому что я изучил необработанный текст (с echo) непосредственно перед записью его в канал STDIN сценариев perl, и я проверил свой сценарий perl непосредственно на необработанных строках в кодировке url.

Я сейчас добавил скрипт на Perl ниже. Это в основном сводится к мини-работе по уменьшению карты.

use strict;

my %rows;
while(<STDIN>) {
chomp;
my @line = split(/\t/);
my $key = $line[0];
if (defined @rows{$key}) {
for my $i (1..$#line) {
$rows{$key}->[$i-1] += $line[$i];
}
} else {
my @new_row;
for my $i (1..$#line) {
push(@new_row, $line[$i]);
}
$rows{$key} = [ @new_row ];
}
}

my %newrows;
for my $key (keys %rows) {
my @temparray = split(/ /, $key);
pop(@temparray);
my $newkey = join(" ", @temparray);
if (defined @newrows{$newkey}) {
for my $i (0..$#{ $rows{$key}}) {
$newrows{$newkey}->[$i] += $rows{$key}->[$i] > 0 ? 1 : 0;
}
} else {
my @new_row;
for my $i (0..$#{ $rows{$key}}) {
push(@new_row, $rows{$key}->[$i] > 0 ? 1 : 0);
}
$newrows{$newkey} = [ @new_row ];
}
}

for my $key (keys %newrows) {
print "$key\t", join("\t", @{ $newrows{$key} }), "\n";
}

0

Решение

Примечание для себя: всегда проверяйте свои предположения. Оказывается, где-то в моих сотнях миллионов строк ввода были, фактически, буквальные пробелы, где должны были быть закодированные URL-адреса. Чтобы найти их, потребовалось некоторое время, так как были сотни миллионов правильных буквальных пространств, но они были.

Извините ребята!

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]