Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > найти позиции заданных подстрок в конце


Автор: kefi 20.11.2008, 15:16
Такая задача :
Найти позицию начала последовательности подстрок <Str1>,<Str2>,...,<StrN>в хвосте строки 

Есть строка вида :
<Один или более символов>[<Str1>][<Str2>]...[<StrN>]

[<Str1>],[<Str2>],...,[<StrN>] - хвостовые подстроки стоят только в конце строки, и при этом могут как угодно между собой чередоваться ( повторяться можно, но лучше решить БЕЗ повторений , т.е. для хвоста wabbaab найти не 2-ю(с 1-цы считая), а 6-ю позицию ) . Например: "Это начало С1D1E1" или "Это начало E1C1" .
Здесь [...] - синтаксис текста, который может быть опущен

Нужно построить шаблон регулярного выражения находящего 1-ю позицию вхождения заданных  хвостовых подстрок Str1,Str2,...,StrN и соовтетсвенно какой подстроке она соответствует.

PS Вообще кроме этого желаетльно также найти и все позиции всех остальных хвостовых подстрок.

НАпример для подстрок  "a", "b", "c" :
Pattern = "(a|b|c)$" 
testString="qabc" ну или testString="qcb" ну или testString="qbac" etc 
плохое решение так как находится только позиция последней подстроки "c", а нужно найти позицию первой полдстроки "a" .
как это сделать ?

Перенесено из последних постов :

Решение :
(((Str1)|(Str2)|(Str3))?(?!.*\2.*))+$

и Область применения :
Ну и еще о практическом применении :
нужно обработать командную строку вышеупомянутого вида, в конце которой стоят в произвольном порядке ключи, причем если эти же ключи в стречаются в самой строке , то семантически они должны рассматириваться уже не как ключи, а ка текст команды.
<Команда с возможными включениями последовательностей символов тождественных ключевым><ключ1><ключ2><ключ3>...
например : "Хочу мороженого,хочу пирожногоог"
Ключ "о" - означает с оладьями
Ключ "г" - означает с глазурью (ну это не важно, что они означают)

шаблон (((о)|(г))?(?!.*\2.*))+$ сработает верно для такой строки , 

а вот первый вариант шаблона ((о)|(г))+$ сработает верно только  для строки "Хочу мороженого,хочу пирожного ог"

Автор: shamber 20.11.2008, 16:02
kefi
как это сделать за Вас? 
Тогда в раздел Работа

Автор: kefi 20.11.2008, 17:03
Цитата(shamber @ 20.11.2008,  16:02)
kefi
как это сделать за Вас? 
Тогда в раздел Работа >


Ух-ты - первыый пост в форуме и сразу на чудика нарвался !

Автор: tolkien 20.11.2008, 18:54
Разделите ваш большой шаблон на множество мелких.  Уберите или
Pattern = ".+(a|b|c)$"   ---> Pattern1= ".+a$" Pattern2= ".+b$" Pattern3= ".+c$"
ищите по отдельности

А хамить на форуме не надо. 

Автор: kefi 20.11.2008, 22:20
Цитата(tolkien @ 20.11.2008,  18:54)
Разделите ваш большой шаблон на множество мелких.  Уберите или
Pattern = ".+(a|b|c)$"   ---> Pattern1= ".+a$" Pattern2= ".+b$" Pattern3= ".+c$"
ищите по отдельности

А хамить на форуме не надо.

  Я тоже считаю , что хамить не надо  - про хамство это не ко мне - это к shamber, который считает , что любой вопрос на форуме надо отсылать ему в "Работу" и платить ему за это ДЕНЬГИИИ , другими словами , что  из всех разеделов на форуме нужно оставить только один  "Работа" - вот это уже даже покруче, чем хамство ,  и моя реакция очень мягкая.

А вопрос-то  недалекий был , просто для меня - новичка в регексах  -  непонятный :
Шаблон , как оказалось должен быть :  "(a|b|c)+$" 

Может, обсудим теперь - как это все работает и придумаем как его усовершенствовать  для получения позиции каждой подстроки в хвосте , Например, a,b,c  для строки "qabc_acbac" , т.е. позиции 5,6,7,8,9  ( но не 1,2,3! ) ?


Автор: kefi 20.11.2008, 23:46
Вот этот шаблон "((a)|(b)|©)+$",
 только почему он работает - не могу догнать никак , может кто объяснит ?

Автор: ginnie 21.11.2008, 13:06
kefi, в шаблоне указано, что ему соответствует подстрока с любым количеством и в любом порядке символов a, b и c (но только эти символы) в конце строки. Аналогично /[abc]+$/.

Автор: kefi 21.11.2008, 19:16
ginnie, да нет - читайте первый пост : вместо символов a,b,c примера могут быть любые последовательности символов

Тут возникла другая трабла, захотелось вот чего : 

Желательно, чтобы находилась позиция подстрок в хвосте и они начиная с нее НЕ ПОВТОРЯЛИСЬ .

Т.е. , например ,для шаблона (a|b)+$ могут быть в конце строки найдены образцы, например :
abbaab
baaa
bbabb
Причем будет найдена первая позиция встречи этих образцов в хвосте строки, а нужно (ну точнее, желательно) , чтобы была найдена позиция выделенных кусков.

Автор: tolkien 21.11.2008, 21:58
Я честно пытался перевести то что вы выше написали но то что после bbabb не смог осилить 
...
Для шаблона (a|b)+$ соответ след. строки 
abbaab
baaa
bbabb


Что нужно? Приведите пример полный что имеете вы на входе и что на выходе желаете получить 

Автор: kefi 22.11.2008, 09:34
tolkien, пардон , просто в том посте http://forum.vingrad.ru/forum/topic-236991/anchor-entry1705379/0.html# куски в хвостах не выделил , сейчас исправил ( просто примените шаблон (a|b)+$ к строкам abbaab или baaa или bbabb , и Вы увидите, что будет найдена первая позиция вместо выделенных ) :
Кажись так в нотации перла :
 print "Это ab на последнем вхождении ?.." if 'abbaab' =~ /(a|b)+$/gis;
 ...

Автор: amg 22.11.2008, 10:56
kefi, по-прежнему не до конца понятно, что Вы хотите.
Присоединяюсь к просьбе tolkien дать пример реальной задачи (не упрощая ее до ab), что имеем на входе, что нужно получить на выходе.

P.S. Возможно, Вам кажется, что Вы исчерпывающе объяснили суть проблемы, но, поверьте, это не так, и именно поэтому Вам не помогли с решением.

Автор: tolkien 22.11.2008, 12:59
Цитата(kefi @ 22.11.2008,  09:34)
tolkien, пардон , просто в том посте http://forum.vingrad.ru/forum/topic-236991/anchor-entry1705379/0.html# куски в хвостах не выделил , сейчас исправил ( просто примените шаблон (a|b)+$ к строкам abbaab или baaa или bbabb , и Вы увидите, что будет найдена первая позиция вместо выделенных ) :
Кажись так в нотации перла :
 print "Это ab на последнем вхождении ?.." if 'abbaab' =~ /(a|b)+$/gis;
 ...

Код

print $1,"\n" if ('abbaab' =~ m/(a|b)+$/gis);
print $1,"\n" if ('baaa' =~ m/(a|b)+$/gis);
print $1,"\n" if ('bbabb' =~ m/(a|b)+$/gis);

Вывод:
b
a
b


Вывод является первое вхождение подстрок а или b с конца строки.

А вам что нужно? 
Чтобы вывод был какой? 

Автор: kefi 22.11.2008, 13:55
amg
tolkien >
Еще подкорректировал первый свой пост .

И Вот, вроде нашел как добраться до групп с искомыми подстроками :  (((a)|(b)|©?(?!.*\2.*))+$
це в скобках упорно превращается в посте в ©
0 группа - внешние скобки (...)+
1 группа - скобки ((a)|(b)|©)?
2 группа -  скобки (a)
3 группа -  скобки (b)
4  группа -  скобки ©
НАпример для 'abcb' =~/(((a)|(b)|©)?(?!.*\2.*))+$/gis  (perl) будут для коллекции SubMatches (vbs) уже  найдены для подстроки "a" - пусто, "b" - "b" и "c" - "c" на соответсвенно 2,3 и 4 местах колекции SubMatches.

Вот только еще не понял - а 5 группа (?!.*\2.*) - вроде как и не группа для сравнения что ли? Ее как-то не находится вообще ? Может кто понимает ?

Автор: kefi 22.11.2008, 14:25
Ну и еще о практическом применении :
нужно обработать командную строку вышеупомянутого вида, в конце которой стоят в произвольном порядке ключи, причем если эти же ключи в стречаются в самой строке , то семантически они должны рассматириваться уже не как ключи, а ка текст команды.
<Команда с возможными включениями последовательностей символов тождественных ключевым><ключ1><ключ2><ключ3>...
например : "Хочу мороженого,хочу пирожногоог"
Ключ "о" - означает с оладьями
Ключ "г" - означает с глазурью (ну это не важно, что они означают)

шаблон (((о)|(г))?(?!.*\2.*))+$ сработает верно для такой строки , 

а вот первый вариант шаблона ((о)|(г))+$ сработает верно только  для строки "Хочу мороженого,хочу пирожного ог"

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)