2013-11-24 2 views
1

Я пытаюсь заменить некоторые цифры в строке с использованием переменных, и я столкнулся с проблемами, которые я не могу решить. После ввода:Perl - замена числовых строк на содержимое переменной

111111 133433.000 222222 5225.9860 360 01333.4400 90 10.37 137.71 190410 
    111111 133434.000 222222 5225.9837 360 01333.4432 90 1.11 138.34 190410 

Скрипт должен заменить значение 1.11 во второй строке с 10.37 от первой линии. В обрабатываемом файле имеется несколько тысяч строк, поэтому строки будут оцениваться, а номера 1.11 и 10.37 будут храниться в переменных. В данном конкретном случае:

$speed = 1.11 
$speed_p = 10.37 
$tmpline - current processed line (part of an array) 

Я использую это для замены:

$tmpline =~ s/$speed/$speed_p/eeg; 

, к сожалению, эта команда игнорирует «точку» в $speed и я получаю следующий результат для второй линии:

10.3711 133434.000 222222 5225.9837 360 01333.4432 90 10.37 138.34 190410 

Таким образом, команда заменяет 111 и 1.11 с новым значением, есть способ, чтобы улучшить это и избежать й e "точка" в переменной?

Заранее благодарен!

Alex

+0

Использование двойной оценки '/ ee' не только не обязательно, но и очень опасно и очень плохо. Потому что он выполняет произвольный код в вашей системе. – TLP

ответ

2

Период . является регулярным выражением меты символа, который является подстановочным, он соответствует ничего, кроме символа новой строки \n. Вам нужно отключить мета-статус периода, который обычно выполняется с обратным слэшем. Тем не менее, в вашем случае, вы можете использовать последовательность \Q ... \E побег:

$tmpline =~ s/\Q$speed\E/$speed_p/g; 

Отметим также, что я удалил двойного оценки /ee модификаторов. Они не требуются, и они опасны для использования.

Это не останавливается на достигнутом, поскольку вы все равно можете совместить 1.11 (например, он может соответствовать 21.1123). Таким образом, вы должны убедиться, что вы соответствие весь номер:

$tmpline =~ s/(?<!\S)\Q$speed\E(?!\S)/$speed_p/g; 

я использую двойное отрицание здесь, с просмотром назад и опережения утверждение, чтобы убедиться, что символы по обе стороны от вашего номера не без -whitespace. Двойное отрицание предназначено для обработки крайних случаев, поскольку оно считает начало или конец строки приемлемым. Если у вас всегда есть пробелы вокруг вашего номера, вы можете просто использовать (?<=\s) и (?=\s).

+0

Отлично! Теперь он работает так, как нужно и спасибо за улучшение/lookhhead! – user3027011

+0

Добро пожаловать. – TLP

Смежные вопросы