Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменение содержимого текстовго файла 
:(
    Опции темы
ma_lover
Дата 1.11.2007, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Помогите решить проблем..Нужно считать инфу из текстового файла, модифицировать её и записать в другой текстовый файл..Модифицировать-поменять регистр с нижнего на верхний+провести замену некоторых символов на другие, добавить поле вычисления длины и так далее в том же духе...Пока добился того, что во второй файл пишет инфу в верхнем регистре, но..упорно не хочет заменять.И ещё подскажите, зачем в цикле while-к примеру- указывать явное соответсвие дескриптора-файлу, когда во всех книгах пишут, что они итак взаимно однозначны? пробовал без этого-не заработало, пока не поменял.Подскажите , плиз, ибо книги подробной инфы не дают.
Спасибо.Ниже код:

#! usr/bin/perl -w

$file_in="in.txt" unless defined $file_in;
$file_out="out.txt"  unless defined $file_out;

printf "Opening file for conversion...\n";
open(INFILE,'<',$file_in) or die ("Cannot open file: $!");
open(OUTFILE, '+>',$file_out) or die ("Can't open output file: $!");

register_change($file_in,$file_out);

# Change every symbol's register to UP
sub register_change{

while ($file_in=<INFILE>)  {
print OUTFILE $file_out=uc($file_in);
$file_out=~ tr/S/T/;
}

}

close INFILE or die ("Cannot close file: $!");
close OUTFILE or die ("Cannot close file: $!");

print "Successful conversion.\n";
PM MAIL   Вверх
BlackLFL
Дата 1.11.2007, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



Код

#!/usr/bin/perl
use strict;
use warnings;

print "Content-type: text/html\n\n";

local *IN;
local *OUT;

open( IN, "1.txt" ) or die $!;
flock( IN, 2 );
open( OUT, ">2.txt" ) or die $!;
flock( OUT, 2 );
while( <IN> )
{
    $_ = uc( $_ );
    s/S/T/g;
    
    print OUT;
}
close( OUT ) or die $!;
close( IN ) or die $!;

1;


Это сообщение отредактировал(а) BlackLFL - 1.11.2007, 17:18
PM WWW   Вверх
ma_lover
Дата 1.11.2007, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



После долгих мучений справился сам вот таким образом:

Код

#! usr/bin/perl -w

$file_in="in.txt" unless defined $file_in;
$file_out="out.txt"  unless defined $file_out;

printf "Opening file for conversion...\n";
open(INFILE,'<',$file_in) or die ("Cannot open file: $!");
open(OUTFILE, '+>',$file_out) or die ("Can't open output file: $!");

register_change();

# Change every symbol's register to UP
sub register_change{
my $temp1;
while (my $line1=<INFILE>)  {
$temp1=uc($line1);
$temp1=~ tr/SENT/Tx  /;
print OUTFILE $temp1;
}

}
close INFILE or die ("Cannot close file: $!");
close OUTFILE or die ("Cannot close file: $!");

PM MAIL   Вверх
ma_lover
Дата 1.11.2007, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Возник правда ещё один вопрос.Каким образом можно в строку с определённой точки в тсроке вставить набор символов и каким образом их потом подвигать по надобности?
PM MAIL   Вверх
BlackLFL
Дата 2.11.2007, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



Цитата

root>perldoc -f substr
    substr EXPR,OFFSET,LENGTH,REPLACEMENT
    substr EXPR,OFFSET,LENGTH
    substr EXPR,OFFSET
            Extracts a substring out of EXPR and returns it. First character
            is at offset 0, or whatever you've set $[ to (but don't do
            that). If OFFSET is negative (or more precisely, less than $[),
            starts that far from the end of the string. If LENGTH is
            omitted, returns everything to the end of the string. If LENGTH
            is negative, leaves that many characters off the end of the
            string.

            You can use the substr() function as an lvalue, in which case
            EXPR must itself be an lvalue. If you assign something shorter
            than LENGTH, the string will shrink, and if you assign something
            longer than LENGTH, the string will grow to accommodate it. To
            keep the string the same length you may need to pad or chop your
            value using "sprintf".

            If OFFSET and LENGTH specify a substring that is partly outside
            the string, only the part within the string is returned. If the
            substring is beyond either end of the string, substr() returns
            the undefined value and produces a warning. When used as an
            lvalue, specifying a substring that is entirely outside the
            string is a fatal error. Here's an example showing the behavior
            for boundary cases:

                my $name = 'fred';
                substr($name, 4) = 'dy';            # $name is now 'freddy'
                my $null = substr $name, 6, 2;      # returns '' (no warning)
                my $oops = substr $name, 7;         # returns undef, with warnin
g
                substr($name, 7) = 'gap';           # fatal error

            An alternative to using substr() as an lvalue is to specify the
            replacement string as the 4th argument. This allows you to
            replace parts of the EXPR and return what was there before in
            one operation, just as you can with splice().

            If the lvalue returned by substr is used after the EXPR is
            changed in any way, the behaviour may not be as expected and is
            subject to change. This caveat includes code such as
            "print(substr($foo,$a,$b)=$bar)" or
            "(substr($foo,$a,$b)=$bar)=$fud" (where $foo is changed via the
            substring assignment, and then the substr is used again), or
            where a substr() is aliased via a "foreach" loop or passed as a
            parameter or a reference to it is taken and then the alias,
            parameter, or deref'd reference either is used after the
            original EXPR has been changed or is assigned to and then used a
            second time.

PM WWW   Вверх
ma_lover
Дата 2.11.2007, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Не знаю пока как substr поможет..нужно найти в файле все числа: 1 3 F0 34 0 1  итд. и к тем, который записываются только 1 символом, добавить нули, то есть так, чтобы стало: 01 03 F0 34 00 01...
PM MAIL   Вверх
KSURi
Дата 2.11.2007, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Код

$txt =~ s/(\d{1})/0$1/g



--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ma_lover
Дата 4.11.2007, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Код

$txt =~ s/(\d{1})/0$1/g


добавляет в данном случае нули везде, даже там , где они не нужны..
PM MAIL   Вверх
BlackLFL
Дата 5.11.2007, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



тогда может опишете более подробно, что Вам нужно?
PM WWW   Вверх
amg
Дата 5.11.2007, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Может, так?
Код

s/^(\d\s)/0$1/;
s/(?<=\s)(\d)$/0$1/;
s/(?<=\s)(\d)(?=\s)/0$1/g;


PM MAIL   Вверх
ma_lover
Дата 5.11.2007, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



amg, спасибо,Вы предложили то, что нужно, только вот ещё и шестнадцатиричные символы нужно учесть..то есть может быть строка: 
1 3 А F0 34 0 1..тогда в результате она заменится на строку 01 03 0A F0 34  00 01. BlackLFL, вот более менее подробно, что требуется:

нужно найти в файле все числа: 1 3 A F0 34 0 1  итд. и к тем, которые записываются только 1 символом, добавить нули, то есть так, чтобы стало: 01 03 0A F0 34 00 01...



Это сообщение отредактировал(а) ma_lover - 5.11.2007, 12:20
PM MAIL   Вверх
amg
Дата 5.11.2007, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(ma_lover @  5.11.2007,  12:16 Найти цитируемый пост)
 только вот ещё и шестнадцатиричные символы нужно учесть
Просто заменить \d на [\dA-F] (или на [\da-fA-F]).

PM MAIL   Вверх
ma_lover
Дата 5.11.2007, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



amg, заменил-но не сработало, никаких изменений со строкой не произошло.=-(

Это сообщение отредактировал(а) ma_lover - 5.11.2007, 13:42
PM MAIL   Вверх
amg
Дата 5.11.2007, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Должно работать!
Код

$_ = '1 3 A F0 34 0 1';
s/^([\dA-F]\s)/0$1/;
s/(?<=\s)([\dA-F])$/0$1/;
s/(?<=\s)([\dA-F])(?=\s)/0$1/g;
print "$_\n";


Добавлено через 10 минут и 55 секунд
Эти три регулярки можно объединить:
Код

s/(?:^|(?<=\s))([\dA-F])(?:(?=\s)|$)/0$1/g;

PM MAIL   Вверх
ma_lover
Дата 5.11.2007, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



amg, прошу прощения, всё действительно работает.Это я , по неопытности, []- опустил, с ними всё ок.Спасибо! smile 
PM MAIL   Вверх
ma_lover
Дата 7.11.2007, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Не могли бы вы подсказать, как подсчитать кол-во этих элементов "01 03 0A F0 34" в строке, игнорируя пробелы..
PM MAIL   Вверх
amg
Дата 7.11.2007, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Например, так:
Код

$count++ while $str=~/[\dA-F]{2}/g;

Прошу прощения, корректнее будет уточнить регулярное выражение (два подходящих символа, перед которыми начало строки либо пробел и после которых пробел либо конец строки)
Код

$count++ while $str=~/(?:^|(?<=\s))[\dA-F]{2}(?:(?=\s)|$)/g;


Это сообщение отредактировал(а) amg - 7.11.2007, 13:48
PM MAIL   Вверх
ma_lover
Дата 7.11.2007, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



не могли бы Вы пояснить значение утверждения "?:".."|", как я понял, обеспечивает одновременный учёт всех условий..



Это сообщение отредактировал(а) ma_lover - 7.11.2007, 14:28
PM MAIL   Вверх
amg
Дата 7.11.2007, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Код

$count++ while $str =~ /
(?:        # открывающая "незахватывающая" скобка
  ^          # начало строки (нулевой длины)
  |          # или
  (?<=\s)    # предшествующий пробел (это выражение нулевой длины)
)          # закрывающая скобка
           # потом идут
[\dA-F]{2} # два нужных символа
           # после них
(?:        # Открывающая "незахватывающая" скобка
  (?=\s)     # последующий пробел (нулевой длины)
  |          # или
  $          # конец строки (нулевой длины)
)          # закрывающая скобка
/xg;


PM MAIL   Вверх
ma_lover
Дата 7.11.2007, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



amg,Спасибо большое!

PM MAIL   Вверх
ma_lover
Дата 7.11.2007, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Такой вопрос..нужно удалить двойные пробелы из строки, точнее заменить их на одинарные.
Всё было бы просто,если бы не тот факт,что нужно сделать это, начиная с определённой точки. Поэтому простая замена не годится..То есть в той же строке "01 03  0A F0  34"нужно заменить двойные пробелы на одинарные, при условии, что первый двойной пробел находится перед "01" и как раз его трогать не нужно..Пока сделал только так:
Код

$temp1=~ s/\s{2}([\dA-F]{2})/\ $1/g;


но он и первый двойной убивает=(

Это сообщение отредактировал(а) ma_lover - 7.11.2007, 17:39
PM MAIL   Вверх
amg
Дата 8.11.2007, 07:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(ma_lover @  7.11.2007,  17:25 Найти цитируемый пост)
в строке "01 03  0A F0  34" нужно заменить двойные пробелы на одинарные, при условии, что первый двойной пробел находится перед "01" и как раз его трогать не нужно..
Не понял. Зачем приводить в качестве примера строку, не удовлетворяющую твоему же условию?
Код

1 while $temp1 =~ s/(\s\s01.*)\s\s+/$1 /; # ????


PM MAIL   Вверх
ma_lover
Дата 8.11.2007, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



amg, не понял..чем плох пример?
Дело в том, что в строке могут быть какие угодно комбинации чисел, не обязательно "01".

Это сообщение отредактировал(а) ma_lover - 8.11.2007, 10:31
PM MAIL   Вверх
ma_lover
Дата 8.11.2007, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



родился вопрос по предыдущему ответу..
Код

$count++ while $str=~/(?:^|(?<=\s))[\dA-F]{2}(?:(?=\s)|$)/g;


каким образом Perl может подсчитать соединения и цифр и букв типа "0A" благодаря выражению "[\dA-F]{2}"? Ведь оно говорит о том, что нужно искать либо символ, либо букву, повторённую дважды..однако сочетания тоже каким-то образом учитываются..
Цитата

К сожалению, я опять не понял вопрос


Попробую подробнее..
Код

$count++ while $str=~/(?:^|(?<=\s))[\dA-F]{2}(?:(?=\s)|$)/g;

Код подсчитывает количество "двойных" символов в строке:B4 DA 25 C5  02 40 1A  00 1E  00  01  00 60  01  0A
Если учесть, что в [\dA-F]{2}, заключённое в квадратные скобки  даёт нам класс символов, то получим, что это выражение должно искать дважды повторённую цифру или букву..Но также нужно учитывать и комбинации цифра-буква и буква-цифра, типа 1E..Судя по результату, это выражение всё же учитывает и комбинации, потому что в счётчике хранится общее количество двойных символов.
Вот я бы и хотел уточнить , почему это так, может я чего-то не понимаю.

Это сообщение отредактировал(а) ma_lover - 8.11.2007, 11:15
PM MAIL   Вверх
amg
Дата 8.11.2007, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Пример плох тем, что вместо прояснения ситуации он ее еще больше запутывает. И пробовать код на такой строке бессмысленно, т.к. она, судя по условию задачи, не должна измениться. Дай, пожалуйста, несколько своих строк и что из них должно получиться.

PS. Это относится к предыдущему посту

Добавлено через 4 минуты и 23 секунды
Цитата(ma_lover @  8.11.2007,  10:50 Найти цитируемый пост)
каким образом Perl может подсчитать соединения и цифр и букв типа "0A" благодаря выражению "[\dA-F]{2}"? Ведь оно говорит о том, что нужно искать либо символ, либо букву, повторённую дважды..однако сочетания тоже каким-то образом учитываются..
К сожалению, я опять не понял вопрос


Это сообщение отредактировал(а) amg - 8.11.2007, 10:53
PM MAIL   Вверх
ma_lover
Дата 8.11.2007, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Вот моя исходная строка:
Цитата

14:52:44.230  00  Tx  <HDLC 16><Len  40>  B4 DA 25 C5  02 40 1A  00 1E  00  01  00 60  01  0A  00  02  0A  08 83 10

Начиная,в данном случае, с С5, идут двойные пробелы, которые нужно заменить на одинарные. В то же время весь "заголовок":"14:52:44.230  00  Tx  <HDLC 16><Len  40>  " трогать не нужно, включая и пробел между <Len  40> и B4. Значения всего,кроме заголовка будут меняться, поэтому к ним привязываться бессмысленно.

З.Ы. Получилось полно, но видно иначе было бы неясно, о чём идёт речь.
PM MAIL   Вверх
amg
Дата 8.11.2007, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(ma_lover @  8.11.2007,  11:05 Найти цитируемый пост)
Вот моя исходная строка: ...
Попробуем так:
Код

# Начиная с конца заменять два и более пробелов на один, до тех пор пока этим пробелам  предшествует 
# комбинация символов, которую удается интерпретировать как двузначное 16-ричное число
1 while $str=~s/(?<=\s[\dA-F]{2})\s\s+(.*)$/ $1/;



Это сообщение отредактировал(а) amg - 8.11.2007, 11:37
PM MAIL   Вверх
ma_lover
Дата 8.11.2007, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Цитата

Попробуем так:
Выделить всёкод Perl
    
# Начиная с конца заменять два и более пробелов на один, до тех пор пока этим пробелам  предшествует 
# комбинация символов, которую удается интерпретировать как двузначное 16-ричное число
 while $str=~s/(?<=\s[\dA-F]{2})\s\s+(.*)$/ $1/;



К сожалению выкидывает ошибку:
 
Цитата

syntax error at convert.pl line 40, near "while $str"


Это сообщение отредактировал(а) ma_lover - 8.11.2007, 11:52
PM MAIL   Вверх
amg
Дата 8.11.2007, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(ma_lover @  8.11.2007,  11:51 Найти цитируемый пост)
К сожалению выкидывает ошибку:

А единичка где?
PM MAIL   Вверх
ma_lover
Дата 8.11.2007, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



C еденичкой работает, но удаляет пробелы и из заголовка, который трогать нельзя.. Кстати, какую роль играет еденичка??

Вот ещё обновлённый вариант второго вопроса,если что..

Цитата

К сожалению, я опять не понял вопрос


Цитата

Попробую подробнее..

$count++ while $str=~/(?:^|(?<=\s))[\dA-F]{2}(?:(?=\s)|$)/g;

Код подсчитывает количество "двойных" символов в строке:B4 DA 25 C5  02 40 1A  00 1E  00  01  00 60  01  0A
Если учесть, что в [\dA-F]{2}, заключённое в квадратные скобки  даёт нам класс символов, то получим, что это выражение должно искать дважды повторённую цифру или букву..Но также нужно учитывать и комбинации цифра-буква и буква-цифра, типа 1E..Судя по результату, это выражение всё же учитывает и комбинации, потому что в счётчике хранится общее количество двойных символов.
Вот я бы и хотел уточнить , почему это так, может я чего-то не понимаю.


Это сообщение отредактировал(а) ma_lover - 8.11.2007, 12:17
PM MAIL   Вверх
amg
Дата 8.11.2007, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(ma_lover @  8.11.2007,  12:16 Найти цитируемый пост)
C еденичкой работает, но удаляет пробелы и из заголовка, который трогать нельзя.. Кстати, какую роль играет еденичка??
Да, был косяк. Уточним регэксп:
Код
1 while $str=~s/(?<=\s[\dA-F]{2})\s\s+((?:[\dA-F]{2}(?:\s|$))*)$/ $1/;
Единичка служит телом цикла, означая "ничего не делать".

Цитата(ma_lover @  8.11.2007,  12:16 Найти цитируемый пост)
Код подсчитывает количество "двойных" символов в строке:B4 DA 25 C5  02 40 1A  00 1E  00  01  00 60  01  0A. Если учесть, что в [\dA-F]{2}, заключённое в квадратные скобки  даёт нам класс символов, то получим, что это выражение должно искать дважды повторённую цифру или букву..Но также нужно учитывать и комбинации цифра-буква и буква-цифра, типа 1E..Судя по результату, это выражение всё же учитывает и комбинации, потому что в счётчике хранится общее количество двойных символов.Вот я бы и хотел уточнить , почему это так, может я чего-то не понимаю.
Понятно. [\dA-F] - это символ, представляющий собой цифру или букву (от A до F), порядок перечисления внутри квадратных скобок не важен. [\dA-F]{2} - это два таких символа.
PM MAIL   Вверх
ma_lover
Дата 8.11.2007, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Да, работает, спасибо!



Это сообщение отредактировал(а) ma_lover - 8.11.2007, 14:27
PM MAIL   Вверх
ma_lover
Дата 8.11.2007, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 24.3.2007

Репутация: нет
Всего: нет



Можно только небольшое пояснение по поводу работы оператора s/ / /...Насколько пишут в книгах, он заменяет одно поле другим...то есть в нашем случае:
Код

1 while $str=~s/(?<=\s[\dA-F]{2})\s\s+((?:[\dA-F]{2}(?:\s|$))*)$/ $1/;


 $1 должно была бы заменить последовательность из двух шестнадцатиричных символов с сопровождающими их пробелами..В данном случае этому препятствует символ отрицания захвата":?" или как?.Можно пояснить?.
Спасибо.
PM MAIL   Вверх
amg
Дата 8.11.2007, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Код

1 while $str=~s/(?-ism: # далее будет регэксп без опций ism, но с опцией x, чтобы позволить пробелы и комментарии

# Регэксп состоит из 4-х частей

(?<=\s[\dA-F]{2}) # 1-я часть, нулевой длины

\s\s+             # 2-я часть, два и более пробела

(                 # 3-я часть, в захватывающих скобках (пойдет в $1)
  (?:               # открываем группу (без захвата)
    [\dA-F]{2}       # число
    (?:\s|$)         # за ним - пробел либо конец строки, в незахв. скобках, чтобы ограничить действие ИЛИ
  )*                # закрываем группу и эта группа повторяется сколько угодно раз
)                 # конец 3-й части

$                 # 4-я часть, конец строки, нулевой длины

)/ $1/;        # конец действия опции x и замена

PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1282 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.