Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.04.29;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.008 c
15-1324845002
Юрий
2011-12-26 00:30
2012.04.29
С днем рождения ! 26 декабря 2011 понедельник


15-1324577119
Artem
2011-12-22 22:05
2012.04.29
Как сменить диск при открытии файла в FreePascal?


2-1325679752
zZZ
2012-01-04 16:22
2012.04.29
проверить символы в строке


8-1219132442
young
2008-08-19 11:54
2012.04.29
Как увеличить картинку bmp без потери качества


11-1243010637
MTsv DN
2009-05-22 20:43
2012.04.29
Build и Compile