Автор Тема: Вырезка текста  (Прочитано 13600 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Вырезка текста
« : 16 Августа 2003, 14:22:45 »
Есть строка:

Some text 1 [s: Some text 2] Some text 3 [/s] Some text 4

и регуларное выражение:

$text =~s /.*\\[s\\:\\s*(.*)\\s*\\](.*?)|(.*\\n?)/$1/i;

В итоге получаю $text = "Some text 2", но меня смущает что закрывающихся скобок (]) две, не возникнет ли ситуации когда $text будет получать "Some text 2] Some text 3"? Или все-таки усложнить регулярное выражение до:

$text =~s /.*\\[s\\:\\s*(.*)\\s*\\].*\\[\\/s\\](.*?)|(.*\\n?)/$1/i;
« Последнее редактирование: 17 Августа 2003, 16:11:04 от Phoinix »

Оффлайн metton

  • access granted
  • Старожил
  • ****
  • Сообщений: 320
  • +0/-0
  • 2
    • Просмотр профиля
    • http://bluejack.ru/
Вырезка текста
« Ответ #1 : 17 Августа 2003, 04:52:35 »
Не проверяя свои размышления и принимая во внимание время в которое я это пишу, могу сказать следующее:
имхо, из-за жадности квантификатовров при первом шаблоне $text будет иметь значение Some text 2] Some text 3 [/s]
 BlueJacking среди нас

Оффлайн metton

  • access granted
  • Старожил
  • ****
  • Сообщений: 320
  • +0/-0
  • 2
    • Просмотр профиля
    • http://bluejack.ru/
Вырезка текста
« Ответ #2 : 17 Августа 2003, 04:58:23 »
Извиняюсь, опечатался:
Some text 2] Some text 3 [/s
 BlueJacking среди нас

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Вырезка текста
« Ответ #3 : 17 Августа 2003, 16:12:10 »
metton
Нет он возвращает правильное значение - Some text 2, но все-таки буду использовать второй вариант...

Просто интересно как возможно поведет себя регулярное выражение, на практике так как нужно, а в теории???

Оффлайн metton

  • access granted
  • Старожил
  • ****
  • Сообщений: 320
  • +0/-0
  • 2
    • Просмотр профиля
    • http://bluejack.ru/
Вырезка текста
« Ответ #4 : 24 Августа 2003, 02:27:35 »
2Phoinix
Ответ, конечно, поздноват, но всё же...

Вот тест-код:

-----------------------------------------------------------------------------------
#!/usr/bin/perl -w

use strict;
use CGI qw(:all);

print header;

my $text = "Some text 1 [s: Some text 2] Some text 3 [/s] Some text 4";

print $text.\'
\';
$text =~ s/.*\\[s\\:\\s*(.*)\\s*\\](.*?)|(.*\\n?)/$1/i;
print $1.\'
\';
print $text.\'
\';
-----------------------------------------------------------------------------------


У меня, как я и предполагал, выдаёт:

-----------------------------------------------------------------------------------
Some text 1 [s: Some text 2] Some text 3 [/s] Some text 4
Some text 2] Some text 3 [/s
Some text 2] Some text 3 [/s Some text 4
-----------------------------------------------------------------------------------

Т.е. $1 выдаёт именно то что я сказал, а $text совсем не то, что тебе нужно.

И ещё: (.*?)
Тебе не кажется, что метасимвол \'?\' здесь излишен?
« Последнее редактирование: 24 Августа 2003, 02:42:07 от metton »
 BlueJacking среди нас

Оффлайн Yukko

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1586
  • +0/-0
  • 0
    • Просмотр профиля
    • http://estrabota.com.ua
Вырезка текста
« Ответ #5 : 24 Августа 2003, 12:03:23 »
Цитировать
metton:
что метасимвол \'?\' здесь излишен?

лишний!
работа в Украине

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Вырезка текста
« Ответ #6 : 24 Августа 2003, 16:04:54 »
Может и лишний, но хуже от него не становится...
После доработки пришел к такому решению:

$text =~s /.*\\[s\\:\\s*(([1-2A-Za-zА-Яа-яё\\d]+)|([A-Za-zА-Яа-яё\\d]+[A-Za-zА-Яа-яё\\s\\d]+[A-Za-zА-Яа-яё\\d]+))\\s*\\](.*?)|(.*\\n?)/$1/gi;

Вот только меня группа [А-Яа-яё] смущает... никто не знает как она выглядит в HEX формате?

Оффлайн metton

  • access granted
  • Старожил
  • ****
  • Сообщений: 320
  • +0/-0
  • 2
    • Просмотр профиля
    • http://bluejack.ru/
Вырезка текста
« Ответ #7 : 24 Августа 2003, 16:41:38 »
2Phoinix
Просто из любопытсва: а как у тебя с первоначальным выражением $text получился равным \'Some text 2\'?

PS: зря ты всё-таки не слушаешь совета (убрать \'?\'). Этот метасимвол здесь воообще ни на чо не влияет - так зачем лишний символ и лишняя работа парсеру?
 BlueJacking среди нас

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Вырезка текста
« Ответ #8 : 24 Августа 2003, 17:18:11 »
metton
сложно сказать, но одно время работало... проверять не стал, т.к. перешел на второй вариант, но он тоже не подошел... т.к. в тексте может еще сущестовать символы ]

Мало того, я еще думаю в начале поставить ^ - что бы было понятно.
IMHO это не лишняя работа парсеру, а ограничивание вариантов для парсера

Оффлайн metton

  • access granted
  • Старожил
  • ****
  • Сообщений: 320
  • +0/-0
  • 2
    • Просмотр профиля
    • http://bluejack.ru/
Вырезка текста
« Ответ #9 : 24 Августа 2003, 21:50:36 »
2Phoinix
Понимаешь, в данном контексте ((.*?)) метасимвол \'?\' ничего не ограничивает. Он означает ноль или один символ (предшествующий ему), а метасивол \'*\' означает ноль или более симолов. Следовательно, \'?\' не играет в данном контексте НИКАКОЙ РОЛИ!
 BlueJacking среди нас

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Вырезка текста
« Ответ #10 : 25 Августа 2003, 10:30:19 »
metton
Приношу извинения... опечатался, не ? а $ - окончание строки....

P.S. Последний ремикс:

$text =~s /^.*\\[s\\:\\s*(([А-Яа-яё\\w]+)|([А-Яа-яё\\w]+[А-Яа-яё\\s\\w]+[А-Яа-яё\\w]+))\\s*\\].*\\[\\/s](.*$)|(.*\\n$)/$1/gi;
« Последнее редактирование: 25 Августа 2003, 10:40:04 от Phoinix »

Оффлайн metton

  • access granted
  • Старожил
  • ****
  • Сообщений: 320
  • +0/-0
  • 2
    • Просмотр профиля
    • http://bluejack.ru/
Вырезка текста
« Ответ #11 : 26 Августа 2003, 21:55:27 »
2Phoinix
Хочу извиниться - поторопился... Забавно, но, оказалось, что тот треклятый (:)) метасимвол \'?\' даже очень значим в шаблонах типа /.*?/. Читая "книгу с верблюдом" сегодня, обнаружил сей факт (причём где-то во введении). \'?\' в вышеуказанном шаблоне играет роль уменьшения жадности квантификаторов (в данном случае \'*\'). Т.е. шаблон ищет не самое длинное соответствие шаблону, а, наоборот, - самое короткое. И самое забавное - это то, что данный факт позволяет хорошо оптимизировать твой шаблон.
Т.е. для строки "Some text 1 [s: Some text 2] Some text 3 [/s] Some text 4", чтобы вытащить "Some text 2", используем такое:
$text =~ /.*?\\[s\\:\\s*(.*?)\\]/i;
А после, соответственно, находим "Some text 2" в $1.
Чтобы вытащить ещё что-то из этой строки, действуешь соответственно.

ОФФТОП:
2ALL
Я где-то читал, что локальные наборы символов по идее должны входить в класс \\w. А у меня почему-то не входят, а входит только в \'.\' От чего это зависит?
 BlueJacking среди нас

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Вырезка текста
« Ответ #12 : 27 Августа 2003, 10:16:56 »
metton
Насколько я понял в класс \\w входят только латинские символы, цифры и _ , а с кириллицей возникает проблема, поэтому и приходится дополнительно задавать кириллические символы:
[а-яА-ЯёЁ\\w]

Оффлайн metton

  • access granted
  • Старожил
  • ****
  • Сообщений: 320
  • +0/-0
  • 2
    • Просмотр профиля
    • http://bluejack.ru/
Вырезка текста
« Ответ #13 : 27 Августа 2003, 17:30:18 »
2Phoinix
Так есть точка, в которую входят и кириллические.
 BlueJacking среди нас

Оффлайн Alone

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 182
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Вырезка текста
« Ответ #14 : 27 Августа 2003, 17:53:33 »
"." соответствует ЛЮБОМУ символу (исключя \\n, по умолчанию)

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28