Построение регулярного выражения для поиска и редактирования - PullRequest
1 голос
/ 02 июня 2009

Я пытаюсь создать регулярное выражение для поиска и замены файла. Ниже приведен сценарий.

#!use/bin/perl 
use strict; 
use warnings; 
my $line = $ARGV[0]; 
my $find = "[^a-zA-Z0-9]+seqfile[^a-zA-Z0-9]+=[^a-zA-Z0-9]+[a-z]+.."; 
my $replace = "done"; open (FILE, ">>/home/user/Desktop/test") || die "cant open file \n"; 
my @body = <FILE>; 
foreach $line (@body) { 
if (my $line =~ s/$find/$replace/g){ 
print FILE $line;
} 
else { 
print "did not replace \n\n"; 
} 
} 
close(FILE); 
print "reached here\n"; 
exit;

Образец тестового файла, который я запускаю для тестирования моей программы, состоит из нескольких строк текста. Строка, которую я хочу заменить, присутствует в первой строке и является "tobereplaced = file.aa" . Мне пришлось использовать carot (^) для символов, отличных от букв / цифр, потому что регулярное выражение для пробела "\ s" не принято в моей системе. Я знаю, что программа выполняется, потому что она печатает «достигнуто здесь». Может ли кто-нибудь предложить

  1. почему моя программа не может поиск строки с помощью регулярного выражения I указать.
  2. Почему моя система не распознает '\ s' и выдать ошибку "Нераспознано побег прошел через тест "
  3. А также, кто-нибудь может предложить некоторые хороший источник для изучения регулярных выражений.

Спасибо

Ответы [ 2 ]

3 голосов
/ 02 июня 2009

\s не принимается, потому что вы используете строку в двойных кавычках. Строка в двойных кавычках пытается понять смысл \s и не знает, что с ней делать, вы можете сказать что-нибудь из следующего, чтобы она работала:

  • "\\s+seqfile\\s+=\\s+[a-z]+.."
  • '\s+seqfile\s+=\s+[a-z]+..'
  • qr/\s+seqfile\s+=\s+[a-z]+../

Последняя является предпочтительной формой, потому что она создает скомпилированное регулярное выражение, которое будет быстрее обычной строки. Скомпилированное регулярное выражение преобразуется в строку, если вы используете его в контексте, который не ожидает регулярного выражения, поэтому вы можете сказать

print "$find\n";

и вернитесь (?-xism:\s+seqfile\s+=\s+[a-z]+..).

Кроме того, если вы собираетесь отрицать класс символов, вы должны поместить курсор в класс символов: [^a-zA-Z0-9] означает не буквенно-цифровой (по крайней мере, для ASCII), но ^[a-zA-Z0-9] означает совпадение буквенно-цифрового в начале строка (или начало строки, если установлена ​​опция /m).

Кроме того, когда файл открывается в режиме >>, вы не можете прочитать его. Я изменил ваш код для чтения из STDIN (или файлов в командной строке) и записи в STDOUT. Это стандартная техника Perl, называемая фильтрацией. Позволяет строить конвейеры программ. Вы можете запустить скрипт так:

./script.pl inputfile > outputfile

или это

cat inputfile | ./script.pl > outputfile

Вот сценарий

#!use/bin/perl 

use strict; 
use warnings; 

my $find    = qr{ \s+ seqfile \s+ = \s+ [a-z]+ .. }x; 
my $replace = "done";

while (<>) {
    s/$find/$replace/g;
    print;
} 

Это также может быть сведено к одной строке:

perl -pe 's/\s+seqfile\s+=\s+[a-z]+../done/g' inputfile

Хорошие источники для изучения регулярных выражений:

0 голосов
/ 02 июня 2009

Вы открыли файл в режиме добавления, а затем попытались прочитать и записать его. Можно как читать, так и записывать в файл, но вам нужно использовать другой режим. Но если вы не хотите заменить точно такое же количество символов, вам придется читать из одного файла и записывать все (как измененные, так и неизмененные части) во второй файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...