Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2012.04.29;
Скачать: [xml.tar.bz2];

Вниз

Знатокам регулярных выражений   Найти похожие ветки 

 
Sergey Masloff   (2011-11-19 17:24) [0]

Есть длинная строка примерно такого вида
"5\nAfghanistan (Afghani) 69.2183 1.4346 43.3400 0.0000 60.2643 0.9578 57.1994 0.7340Germany (Euro) 1.1486 0.0057 0.7192 -0.0116 1.0000 0.0000 0.9491 -0.0030Pakistan (Pak. Rupee) 138.660 3.0693 86.8200 0.1250 120.723 2.0898 114.584 1.6333\nAlbania (Lek) 162.106 1.3734 101.500 -1.2700 141.136 0.5053 133.958 0.0645Ghana (Cedi) 2.5482 -0.0003 1.5955 -0.0340 2.2185 -0.0113 2.1057 -0.0172Panama (Balboa) 1.5971"

Нужно из нее выделить группы страна-в скобках код валюты-девять числовых столбцов. Если бы страна всегда была одним словом то нет проблем:
"(\S+)\s+\((\S+)\)\s+(\d+\.\d*)\s+(\S+)\s+(\d+\.\d*)\s+(\S+)\s+(\d+\.\d*)\s+(\S+)\s+(\d+\.\d*)\s+(\S+)"

Но это не так. Вобщем пока на уровне словесного описания - страну можно определить как последовательность латинских букв и пробелов, которая начинается с большой латинской буквы. Перед названием страны предыдущие 2 символа это:
-две цифры
или
-цифра пробел
или
- цифра конец строки

пока додумался в первой скобке вместо /S+
написать ([A-Z][A-Z|a-z| ]+)

теперь видимо нужно написать что-то перед первой скобкой. Но никак не соображу что.


 
sniknik ©   (2011-11-19 17:36) [1]

> на уровне словесного описания
восемь чисел разделенных пробелами... если идти с конца. дальше игнор до первой цифры и начинай сначала... зачем регулярки?


 
xayam ©   (2011-11-19 18:36) [2]


> (\S+)\s+\((\S+)\)\s+(\d+\.\d*)\s+(\S+)\s+(\d+\.\d*)\s+(\S+)\s+(\d+\.
> \d*)\s+(\S+)\s+(\d+\.\d*)\s+(\S+)

жжешь :)

код:


header ( "Content-Type: text/plain; charset=utf-8" );
$a = "5\nAfghanistan (Afghani) 69.2183 1.4346 43.3400 0.0000 60.2643 0.9578 57.1994 0.7340Germany (Euro) 1.1486 0.0057 0.7192 -0.0116 1.0000 0.0000 0.9491 -0.0030Pakistan (Pak. Rupee) 138.660 3.0693 86.8200 0.1250 120.723 2.0898 114.584 1.6333\nAlbania (Lek) 162.106 1.3734 101.500 -1.2700 141.136 0.5053 133.958 0.0645Ghana (Cedi) 2.5482 -0.0003 1.5955 -0.0340 2.2185 -0.0113 2.1057 -0.0172Panama (Balboa) 1.5971";

preg_match_all(

        "#([a-zA-Z ]+)\s*\(\s*([a-zA-Z\. ]+)\s*\)\s*([0-9\.\- ]+)#",
         $a, $matches

              );

print_r( $matches );

?>


вывод:


Array
(
   [0] => Array
       (
           [0] => Afghanistan (Afghani) 69.2183 1.4346 43.3400 0.0000 60.2643 0.9578 57.1994 0.7340
           [1] => Germany (Euro) 1.1486 0.0057 0.7192 -0.0116 1.0000 0.0000 0.9491 -0.0030
           [2] => Pakistan (Pak. Rupee) 138.660 3.0693 86.8200 0.1250 120.723 2.0898 114.584 1.6333
           [3] => Albania (Lek) 162.106 1.3734 101.500 -1.2700 141.136 0.5053 133.958 0.0645
           [4] => Ghana (Cedi) 2.5482 -0.0003 1.5955 -0.0340 2.2185 -0.0113 2.1057 -0.0172
           [5] => Panama (Balboa) 1.5971
       )

   [1] => Array
       (
           [0] => Afghanistan
           [1] => Germany
           [2] => Pakistan
           [3] => Albania
           [4] => Ghana
           [5] => Panama
       )

   [2] => Array
       (
           [0] => Afghani
           [1] => Euro
           [2] => Pak. Rupee
           [3] => Lek
           [4] => Cedi
           [5] => Balboa
       )

   [3] => Array
       (
           [0] => 69.2183 1.4346 43.3400 0.0000 60.2643 0.9578 57.1994 0.7340
           [1] => 1.1486 0.0057 0.7192 -0.0116 1.0000 0.0000 0.9491 -0.0030
           [2] => 138.660 3.0693 86.8200 0.1250 120.723 2.0898 114.584 1.6333
           [3] => 162.106 1.3734 101.500 -1.2700 141.136 0.5053 133.958 0.0645
           [4] => 2.5482 -0.0003 1.5955 -0.0340 2.2185 -0.0113 2.1057 -0.0172
           [5] => 1.5971
       )

)


 
Sergey Masloff   (2011-11-19 20:11) [3]

sniknik ©   (19.11.11 17:36) [1]
Не пойдет. Я выделил значимую часть - на самом деле там есть хедер и футер неопределенного формата. Таким способом я одной операцией получаю табличный массив нужных мне данных из любой строки в произвольном месте которой есть кусок подходящий мне по формату


 
Sergey Masloff   (2011-11-19 20:12) [4]

xayam ©   (19.11.11 18:36) [2]
Сейчас посмотрю повнимательнее вроде то что доктор прописал...


 
Sergey Masloff   (2011-11-19 20:14) [5]

p.s. люблю дельфимастер. Суббота вечер... все равно народ адекватно пытается ответить.


 
xayam ©   (2011-11-19 20:25) [6]


> пока додумался в первой скобке вместо /S+
> написать ([A-Z][A-Z|a-z| ]+)

ты наверное имел ввиду ([A-Z][A-Za-z ]+)
В квадратных скобках не нужно указывать символ "или"... там и так все время "или"


 
Sergey Masloff   (2011-11-19 20:37) [7]

xayam ©   (19.11.11 20:25) [6]
Ну я из документации это не понял. А ты мой замысел понял правильно


 
xayam ©   (2011-11-19 21:00) [8]


> А ты мой замысел понял правильно

стало быть теперь я "знаток регулярных выражений"...
Высокое звание :)


 
TUser ©   (2011-11-19 21:12) [9]

Хм, интересно, придумает ли когда-нибудь человечество нечто более вменяемое, чем регулярные выражения?


 
xayam ©   (2011-11-19 21:14) [10]


> придумает ли когда-нибудь человечество нечто более вменяемое,
>  чем регулярные выражения?

они работают. Что ещё нужно?


 
Sergey Masloff   (2011-11-19 21:17) [11]

xayam ©   (19.11.11 21:00) [8]
На самом деле ты реально помог. Я еще одну ошибку попутно нашел сейчас все заработает.


 
xayam ©   (2011-11-19 21:22) [12]


> Я еще одну ошибку попутно нашел сейчас все заработает

Советую посмотреть, если найдешь, эту книгу

http://www.rsdn.ru/res/book/prog/regex10min.xml

маленькая, но очень всё по делу...


 
xayam ©   (2011-11-25 00:40) [13]


> если найдешь, эту книгу

теперь точно найдешь

http://rutracker.org/forum/viewtopic.php?t=3828631


 
Rouse_ ©   (2011-11-25 19:42) [14]


> "#([a-zA-Z ]+)\s*\(\s*([a-zA-Z\. ]+)\s*\)\s*([0-9\.\- ]+)#",

мдя, а вот вопрос - это реально читается? (имеется ввиду спецом по регуляркам)
Ну т.е. вот взглянув на эту производную от brainfuck он с ходу сможет сказать что данное выражение делает?


 
Pavia ©   (2011-11-25 20:01) [15]


> мдя, а вот вопрос - это реально читается? (имеется ввиду
> спецом по регуляркам)

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

> что данное выражение делает?

Это простое.


 
Rouse_ ©   (2011-11-25 20:04) [16]


> Pavia ©   (25.11.11 20:01) [15]

Ну т.е. разбирающемуся в сабже для анализа и модификации (или поиска ошибки) минуты хватит как я понял?


 
Pavia ©   (2011-11-25 20:22) [17]

Разбирающемуся человеку минуты хватит. Но в каждом деле нужна тренировка.


 
Rouse_ ©   (2011-11-25 20:23) [18]

Понятно - пасип :)


 
Омлет ©   (2011-11-25 20:36) [19]


> минуты хватит

Чикушки хватит.


 
xayam ©   (2011-12-26 22:43) [20]

Вот кстати по ссылке
http://www.php.net/download-docs.php
на пересечении колонки "HTML Help file (with user notes)" и строки "Russian"
лежит chm почти на 30 метров.

В нём есть хороший справочник в том числе по регуляркам с комментариями!
(см. раздел Справочник функций/Обработка текста)

обычно пользовался онлайн, а тут и офлайн версия есть... хм...


 
Иксик ©   (2011-12-26 23:03) [21]


> Rouse_ ©   (25.11.11 20:04) [16]
>
>
> > Pavia ©   (25.11.11 20:01) [15]
>
> Ну т.е. разбирающемуся в сабже для анализа и модификации
> (или поиска ошибки) минуты хватит как я понял?


Для этого короткого - да, а вот для такого:
http://ex-parrot.com/~pdw/Mail-RFC822-Address.html
... сомневаюсь! :)


 
Rouse_ ©   (2011-12-26 23:30) [22]


> Иксик ©   (26.12.11 23:03) [21]

Фигасе пазл... Как они это курят? :)


 
xayam ©   (2011-12-27 00:33) [23]


> Как они это курят?

это после курения было написано :)


 
han_malign   (2011-12-27 14:02) [24]


> http://ex-parrot.com/~pdw/Mail-RFC822-Address.html

- взято оттуда и нормализовано:
(DEFINE)(
  (?"LWS":(?:\r\n)?[\x20\t]+)
  (?"lex":[^()<>@,;:\\".\[\]\x20\000-\031]+)
  (?"trash":(?&lex)(?:(?&LWS)+|\Z|(?=[\["()<>@,;:\\".\[\]])))
  (?"sq_trash":(?&trash)|\[([^\[\]\r\\]|\\.)*\](?&LWS)*)
  (?"q_trash":(?&trash)|"(?:[^\"\r\\]|\\.|(?&LWS))*"(?&LWS)*)
  (?"q_domain":\.(?&LWS)*(?&q_trash))
  (?"sq_domain":\.(?&LWS)*(?&sq_trash))
  (?"name":(?&q_trash)(?&q_domain)*)
  (?"host":(?&sq_trash)(?&sq_domain)*)  
  (?"at_host":@(?&LWS)*(?&host))  
  (?"clean_email":(?&name)(?&at_host))
  (?"host_list":@(?&host)(?:,(?&at_host))*:(?&LWS)*)
  (?"tagged_email":(?&q_trash)*\<(?&LWS)*(?&host_list)?(?&clean_email)\>(?&LWS)*)
  (?"email":(?&clean_email)|(?&tagged_email))
)
(?&LWS)*(?:(?&email)|(?&q_trash)*:(?&LWS)*(?:(?&email)(?:,\s*(?&email))*)?;\s*)

- и вот мне интересно, с чего они взяли, что контрольные символы заканчиваются на \031 == 0x19, а не на 0x1F???
- и в классе look-ahead у них символы дублируются (?=[\["()<>@,;:\\".\[\]]), так что без всяких нормализаций шаблон должен быть на 97 символов короче...


 
Андреевич   (2011-12-27 14:47) [25]


> Rouse_ ©   (25.11.11 19:42) [14]
>
> > "#([a-zA-Z ]+)\s*\(\s*([a-zA-Z\. ]+)\s*\)\s*([0-9\.\-
> ]+)#",
>
> мдя, а вот вопрос - это реально читается? (имеется ввиду
> спецом по регуляркам)

в принципе да.
еще есть конструкции с "поиском вперед", помонструознее будет :)
регулярки - это как отдельный мирок :)


 
Андреевич   (2011-12-27 14:53) [26]


> han_malign   (27.12.11 14:02) [24]

мне такое нравится :)
(?:[a-z0-9!#$%&"*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&"*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2012.04.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.003 c
15-1324540812
Фокс Йожин
2011-12-22 12:00
2012.04.29
Глюки IE9 с фреймами


15-1321709041
Sergey Masloff
2011-11-19 17:24
2012.04.29
Знатокам регулярных выражений


15-1324499402
Юрий
2011-12-22 00:30
2012.04.29
С днем рождения ! 22 декабря 2011 четверг


2-1325371999
Gu
2012-01-01 02:53
2012.04.29
строки Xe2


2-1325437970
Каныбек
2012-01-01 21:12
2012.04.29
Возведение в квадрат и извлечение квадратного корня





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский