
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.217.4] |
![]() |
|
Сообщ.
#1
,
|
|
|
Требуется определить, входит ли строка в другую строку, но вне определённого тега.
В примере ниже нужно определить входит ли строка [GG] в строки: "бла бла бла [GG]бла-бла-бла[/GG]" - входит "бла бла бла" - не входит "бла [ CODE ]бла бла[ /CODE]" - не входит "бла бла бла [ CODE ][GG]бла-бла-бла[/GG][ /CODE ]" - входит, НО: если искомая строка "[GG]" входит внутри парного тега [ CODE ] тогда preg_match должен возвращать false. Поэтому не входит. такая строка "бла бла [GG] бла [ CODE ]бла-бла-бла[ /CODE ]" должна вернуть true т.к. [GG] присутствует и находится вне тега [ CODE ]. Хорошо бы, чтобы ещё проверять и [ CODE ] и [GG] - парные. Добавлено strpos, как вы понимаете, я использовать не могу. Вариант, при котором нужно сначала удалить всё что внутри тега [ CODE ], а потом проверять по strpos не подходит, т.к. тормозной. |
Сообщ.
#2
,
|
|
|
Дарю, вот!
![]() ![]() #(?<!\\[CODE\\])\\[GG\\](.*?)\\[/GG\\](?!\\[CODE\\])#i Все приведенные тобой test cases прошли. Кроме того, должно захватить то, что внутри [GG]...[/GG]. |
Сообщ.
#3
,
|
|
|
Спасибо.
Цитата Ho Im @ Кроме того, должно захватить то, что внутри [GG]...[/GG]. Это как понять? |
Сообщ.
#4
,
|
|
|
А, вдогонку: The F*cking Manual, с которого я это почерпнул -- perldoc perlre, полный референс по регуляркам перла. Там рассказывается о таких замечательных вещах, как zero-width look-{ahead,behind} assertions, которые в данном случае делают то, что нужно.
Добавлено Ну, там же .*? намеренно в скобки взят, чтобы потом в третий аргумент preg_match его можно было отловить. |
Сообщ.
#5
,
|
|
|
Ho Im
ещё бы добавить поддержку не только [ CODE ] ... [ /CODE ] а ещё + [ CODE=произвольные_символы_включая_пробелы ] ... [ /CODE ] Внутри них тоже не должно GG срабатывать. |
Сообщ.
#6
,
|
|
|
Держи.
#(?<!\\[CODE.*?\\])\\[GG\\](.*?)\\[/GG\\](?!\\[/CODE\\])#i Учти, в первом примере ошибка (копипейст не работал, и я его руками набивал): в конце смотрит не на[/CODE], а [CODE]. Здесь поправил. Естессно, учитываются все символы до закрывающей квадратной скобки, даже если ее закавычить. Если это не то, что требуется, то надо еще чуть подумать. |
Сообщ.
#7
,
|
|
|
Ho Im
смотри чего php написал: Цитата Warning: Compilation failed: lookbehind assertion is not fixed length at offset 15 in /usr/local/www/votforum/htdocs/TEST/sources/functions.php on line 59 59-ая это: ![]() ![]() preg_match("#(?<!\\[CODE.*?\\])\\[GG\\](.*?)\\[/GG\\](?!\\[/CODE\\])#i", $post) |
Сообщ.
#8
,
|
|
|
А, блин, я слажал -- "смотреть назад" можно только на паттерны фиксированной длины. Подумаем щас, как это обойти. Тебе ничего, кроме ответа да/нет, не надо?
Добавлено "#(?!\\[CODE.*?\\])\\[GG\\](.*?)\\[/GG\\](?!\\[/CODE\\])#i" у меня заработал. |
Сообщ.
#9
,
|
|
|
Советую сделать так:
![]() ![]() preg_match("#\\[GG\\].*?\\[/GG\\](?!(?:(?!\\[CODE.*?\\]).)*?\\[/CODE\\])#i", $post) Будет работать при условии что все теги code парные. ЗЫ Кстати в языках NET можно заглядывать назад на любую глубину ![]() |
Сообщ.
#10
,
|
|
|
Mixxx, это один фиг с моим.
Добавлено Mixxx, [gg]as[/gg][gg]ansa[/gg][ /code ] твоим не пропускается. Моим пропустился. Значит, не один фиг ![]() |
Сообщ.
#11
,
|
|
|
Спасибо, Ho Im
|
Сообщ.
#12
,
|
|
|
Цитата Ho Im @ Mixxx, [gg]as[/gg][gg]ansa[/gg][ /code ] твоим не пропускается. Моим пропустился. Значит, не один фиг Ещё твой пропустит ![]() ![]() [ code ] [GG] [/GG]текст[/ code ] А мой пропустит вот это ![]() ![]() [GG] [/GG][ code ] [/ code ] ![]() |
Сообщ.
#13
,
|
|
|
Mixxx
но всё-таки твой пропускает Цитата Ho Im @ [gg]as[/gg][gg]ansa[/gg][ /code ] ? т.е. он должен возвращать единицу, а он не возвращает. |
Сообщ.
#14
,
|
|
|
Цитата Song @ Mixxx но всё-таки твой пропускает Цитата (Ho Im @ Вчера, 22:51) [gg]as[/gg][gg]ansa[/gg][ /code ] ? т.е. он должен возвращать единицу, а он не возвращает. Я ж говорю что теги code должны быть парными. Т.е. в данном случае полная картина должна выглядеть так [ code ][gg]as[/gg][gg]ansa[/gg][ /code ] Поэтому функция должна возвращать false ![]() |
Сообщ.
#15
,
|
|
|
Вообще-то ошметок тега, который неверно либо спарен, либо сам по себе неверен, должен бы по идее возвращаться в своем первоначальном виде. Как и [GG]. То есть, ничего особенного в нем не должно замечаться.
|
Сообщ.
#16
,
|
|
|
Song, помогу, как смогу.
Вот тебе парсер: преобразует текст с тегами в дерево. Чётность не считается, но дерево проще проанализировать, чем текст. ![]() ![]() $/=undef; sub build_tree { my($tree, $str)=(shift, shift); my($lpos, $item, $tag, $pos)=0; while($str=~m{\[(/?)(.*?)\]}gc) { $tag=uc $2; if(length $1) { next unless $tree->{tag} eq $tag; ($tree->{closed}, $pos)=(1, pos $str); push @{$tree->{cont}}, substr $str, $lpos, $pos-$lpos-length $&; return $pos } ($item, $pos)=({tag=>$tag, cont=>[]}, pos $str); push @{$tree->{cont}}, substr($`, $lpos, $pos - length $&), $item; $lpos=$pos+&build_tree($item, substr $str, $pos); pos($str)=$lpos; } push @{$tree->{cont}}, substr $str, $lpos; +$lpos } sub DOM { my($str, $tree)=(shift || return, shift || {cont=>[]}); &build_tree($tree, $str); +$tree } use Data::Dumper; print Dumper DOM <DATA>; __DATA__ fgth gfhgf [/CDE] [CDE] [GG]klldksfklds34[/GG] ds fds fl;l;dsf [GG] 786893ii [CODE]klldksfklds6[/CDE] klldksfklds7 [/GG] [/CDE] [CDE] sdf dsgfdhfhfgjh [GG]klldksfklds34[/GG] dd fds fl;l;dsf [GG]klldksfklds6[/GG]fhfgjh [/CDE] sdl;f kdsl;f |
Сообщ.
#17
,
|
|
|
Цитата Mixxx @ Я ж говорю что теги code должны быть парными. Т.е. в данном случае полная картина должна выглядеть так [ code ][gg]as[/gg][gg]ansa[/gg][ /code ] Поэтому функция должна возвращать false Парность должна учитываться только в [gg]. В code - нет. А то что я написал Цитата Song @ Хорошо бы, чтобы ещё проверять и [ CODE ] и [GG] - парные. это я не до конца задачу представил себе тогда. Tishaishii, спасибо. |
Сообщ.
#18
,
|
|
|
В коде выше:
![]() ![]() ......... next unless $tree->{tag} eq $tag; ............. Вот здесь можно не делать next, а выдавать ошибку о том, что "парность" не соблюдена. ![]() ![]() die 'Парность не соблюдена' unless $tree->{tag} eq $tag; ![]() ![]() return -1 unless $tree->{tag} eq $tag; |