Jump to content
  • 0

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


solos
 Share

Question

$s='<Т1 day="8" month="12" year="2007">

<Т2 day="9" month="12" year="2007">

<Т3 day="10" month="12" year="2007">';

preg_match_all("/(day|month|year)="([^"]*)"/Us", $s, $tmp);

Как добиться чтобы вытягивало даные имена значений и содержимое в теге <Т2 day="9" month="12" year="2007">, имена могут добавляться например:

$s='<Т1 day="8" month="12" year="2007">

<Т2 day="9" month="12" hour="13" year="2007">

<Т3 day="10" month="12" name="our_name" year="2007">';

Ломал голову и немогу дойти до истины, помогите.

Link to comment
Share on other sites

11 answers to this question

Recommended Posts

  • 0

preg_match_all("/]*((day|month)="([^"]*)")[^>]*>/Us", $s, $tmp);

Вот до чего я дошел но это совсем не то, если писать просто одно имя то все ок, но мне нужно несколько , для этого нужно вставлять блок [^>]*((day|month)="([^"]*)") один за другим, а как бы его выражением прописать?

Link to comment
Share on other sites

  • 0

там ведь T1, T2 везде с T начинаются, а дальше цифра?

"##U" - в $1 получаем все содержимое тэга, т.е. и атрибуты и их значения.

дальше эту строку раскладываем на массив по пробелу - explode()

получаем в итоге

@ {

[0] => 'day="10"'

[1] => 'month="12"'

[2] => 'name="our_name"'

[3] => 'year="2007"'

}

преобразование в такой массив я сделал на случай если в тэге вдруг будет не тот порядок атрибутов, т.е. местами поменяют к примеру. если есть уверенность что подобных изменений не будет, РВ будет примерно таким (проверять лень):

"#

и отредактируй название топика плиз... в первый момент долго пытался понять что такое "регуляторное выражение"... и при чем вообще в php регуляторы

Link to comment
Share on other sites

  • 0

D.S.Denton опять не в ту степь. Я же написал что мне нужно, в Вашем варианте с приличными даными можно голову свернуть и обработка в пару этапов. Долго, нудно и нагрузка.

Еще есть предложения?

Link to comment
Share on other sites

  • 0
с приличными даными можно голову свернуть

мм... приличные данные обычно выдаются XMLем, который распарсивается без подобных извращений. сложных примеров не увидел, а для разбора таких страниц моих обоих вариантов достаточно (http://dc.denton.msk.ru/stats.php сделано как раз почти подобным образом)

обработка в пару этапов. Долго, нудно и нагрузка.

два этапа, создающие нагрузку меньше чем один - это хуже??? шаблонные поиск и/или замена всегда более ресурсоемкая вещь, чем прочие строковые операции, поэтому выбор из тэга необходимого в одну переменную, а затем разбивка строки на подстроки гораздо эффективнее.

недостаток этого - для сложной структуры более сложная обработка, но про то уже сказал выше.

нудно... хм. нудно это разбирать хтмл-код извращенными методами, когда для такого существует (в третий раз скажу и хватит) XML.

Еще есть предложения?

целых два...

1 - если это делается не ради самопознания через медитацию над кодом или решения общей ситуации - давать как и предписано основами программирования граничные ситуации + случай из интервала между ними (т.е. образец одного из самых сложных текстов и самый простейший + средней сложности).

2 -

в Вашем варианте

см подпись. я обращаюсь к людям соответственно их пожеланиям "ты"/"вы", но к себе "вы" не переношу. мне еще нет даже 90 лет. вынос этой инфы в подпись ибо достало, не помогает...

Link to comment
Share on other sites

  • 0

Уважаемый D.S.Denton мне нужно понять "регуляторку". Тобишь каким образом в выражении

preg_match_all("/]*((day|month)="([^"]*)")[^>]*>/Us", $s, $tmp);

заставить искать не одно значение day или month а то и другое.

Проблема тут состоит в том чтобы искало между

а получаться что ищет целое выражение, по этому только находит одно значение.

Нужна одна "регуляторка" которая все бы это делала.

Спасибо за понимание.

Да и еще, есть такое понятие как жадный квантификатор, в даном примере есть какая то логика поиска, что ищет не в даном промежутке () а в целом и получается не то что нужно.

Link to comment
Share on other sites

  • 0
каким образом в выражении

preg_match_all("/]*((day|month)="([^"]*)")[^>]*>/Us", $s, $tmp);

заставить искать не одно значение day или month а то и другое.

раскладываю по шагам:

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

получаем: [color:blue]#]*((day|month)="([^"]*)")[^>]*>#Us

2 - убираем модификатор s. он не надо. а про жадность - это как раз U, который оставляем.

[color:blue]#]*((day|month)="([^"]*)")[^>]*>#U

3 - раскладываем на логические части строку , сразу составляя новое РВ:

# - граница начала РВ

3 - число, которое различается в тэгах. пишем вместо него [d] (любой десятичный символ). добавляем +, означающий что здесь может быть не менее одного такого символа. т.е. выходит [d]+

пробел - так и хочется оставить пробелом, но вдруг их окажется больше одного. поэтому пишем + по аналогии с цифрой

day="10" - мы пока не пишем общий случай, предполагающий отсутствие каких-либо атрибутов у тэга или их другой порядок. потому сделаем day="([d]{1,2})" - ведь день обозначается только цифрами в этой ситуации, причем трехзначных номеров дней в месяце не бывает

month="12" - точно также... month="([d]{1,2})"

name="our_name" - предполагая любой символ в качестве значения, сделаем name="(.+)"

year="2007" - аналогично дню и месяцу, но цифр может быть 2 или 4. year="([d]{2,4})"

вставим везде, где есть пробелы, +. уже говорил зачем

> - закрываем тэг

# - закончилось РВ

U - добавляем "нежадность"

итог: ##U

счас отвлекусь на запись дисков и ребут машины, вернусь

Link to comment
Share on other sites

  • 0
а представь такая лажа поменялись местами day и month

угу. или чего-то отсутствует. поэтому и сказал что еще вернусь:)

квадратные скобки не обязательно писать...

с ними выглядит удобнее (по крайней мере мне так на первый взгляд видно что раз квадратные скобки - тут стоит массив символов. а то что вместо [0-9] используется [d] разницы никакой.

так-с, продолжаем... обзову это как в учебникх обычно формулы обозначают - (1)

##U

с одной стороны хочется сделать как и у тебя - за счет повторяемости приписать "все-в-одном" (day|month)=...

но это заведомо будет неправильным ходом. потребуется ведь все вместе еще взять в внешние скобки и приписать + чтоб обеспечить повторяемость. т.е. окажется что-то типа ((day|month)=(...))+ и вроде оно должно работать...но работать не будет, т.к. поробовав подставить мысленно в это выражение пару значений, увидим что оно будет искать day=...month=..., а надо между ними еще пробел:+)

значит выделяем из (1) части, которые могут поменяться местами или отсутствовать.

1 - day="([d]{1,2})"

2 - month="([d]{1,2})"

3 - name="(.*)"

4 - year="([d]{2,4})"

как уже заметили в предыдущй попытке, между ними должны быть пробелы. так и хочется просто добавить в конец каждой части + и после этого брать в общие скобки, но нет...приглядимся внимательно к последнему атрибуту - после него ведь пробела не будет, а значит он не попадет в выборку. перебарываем порыв добавить пробел в конец и ставим его в начало:+) ведь после T[d]+ там тоже есть пробел.

итого общая скобка (обозначим ее (2)):

(+day="([d]{1,2})"|+month="([d]{1,2})"|+name="(.*)"|+year="([d]{2,4})")+

вот примерно так... а теперь используя (1) и (2), подставленную туда, исправишь свое РВ (мне лень до конца доводить решение)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy