Автор Тема: помогите придумать регулярное выражение  (Прочитано 9967 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн w01k

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 8
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
задача следующая: разделить разряды ЦЕЛОГО числа запятыми слева направо. всё должно быть оформлено в виде s/regexp/.../g. при этом числа могут быть разделены точками

у меня получается только так:
$src =~s/((?:\\D+\\.)|(?:\\s\\d*?))(\\d\\d\\d)(?=(\\d+\\.\\D+)|(\\d+\\s))/\\1\\2,/g;

при этом
исходная строка: ...15785456451  556 88 4   fghd454444    4210101.98752 7895.3545135 984785848 156518..4856..
результат: ...157,85456451  556 88 4   fghd454444    4210101.98752 7895.3545135 984,785848 156,518..485,6..

либо так:
$src =~s/(?
исходная строка: ...15785  556 88 4   fghd454444    4210101.98752 7895.3545135 984785848 156518..4856..
результат: ...157,85  556 88 4   fghd454,444    4210101.9875,2 7895.3545,135 984,785,848 156,518..485,6..

Оффлайн w01k

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 8
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #1 : 03 Июня 2008, 18:44:48 »
строчка
$src =~s/(\\d\\d\\d)||(\\W\\d+\\.\\d+)||([A-Za-z]+\\d+\\W)/\\1/g;
выводит всё, кроме тех чисел и переменных, которые не нуждаются в разделении на разряды.
...15785  556 88 4   fghd454444 4578/456/5/46445:45454:5:45:564556   4210101.98752 7895.3545135 984785848 156518..4856..Testing... OK! It works

...15785  556 88 4   4578/456/5/46445:45454:5:45:564556   984785848 156518..4856..Testing... OK! It works
 как этим воспользоваться - не понимаю(((


можно ли каким-нибудь образом совместить эти строки в одну?
$src =~s/[A-Za-z]+\\d+//g;
$src =~s/\\d+\\.\\d+//g;
$src =~s/(\\d\\d\\d)(?=\\d)/\\1,/g;
они делают, что требуется, правда, удаляют всё, не подходящее под шаблон
исх. строка: ...15785  556 88 4   fghd454444 4578/456/5/46445:45454:5:45:564556   4210101.98752 7895.3545135 984785848 156518..4856..Testing... OK! It works
результат: ...157,85  556 88 4    457,8/456/5/464,45:454,54:5:45:564,556     984,785,848 156,518..485,6..Testing... OK! It works


ещё вопрос, можно писать так:
perl -pe -e \'s///\' -e \'s///\' filename

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #2 : 04 Июня 2008, 10:32:30 »
Цитировать
w01k:
ещё вопрос, можно писать так:
perl -pe -e \'s///\' -e \'s///\' filename


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


Цитировать
w01k:
можно ли каким-нибудь образом совместить эти строки в одну?

возможно и можно. но просмотрев что вы хотите и порядком сломав мозг, думаю что не нужно

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

my $str = \'15785 556 88 4 fghd454444 4578/456/5/46445:45454:5:45:564556 4210101.98752 7895.3545135 984785848 156518..4856..\';
$str.=\' \';
@str=$str=~m/(.*?)\\s/g;
@str=grep{/^(\\d+)$/} @str;
print $_,", " foreach(@str);
« Последнее редактирование: 04 Июня 2008, 12:00:59 от ravshaniy »
убили кенни, сволочи

Оффлайн w01k

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 8
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #3 : 04 Июня 2008, 17:25:55 »
в том то и дело, что задача состоит в том, чтобы решение представляло собой одну строчку. причём запускаемую через командную строку вида:
perl [-p -e -i] \'s/regexp/.../g\'
вот(((

Оффлайн w01k

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 8
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #4 : 04 Июня 2008, 17:52:12 »
нужно не просто вывести все целые числа, разделяя их запятой, а модифицировать исходный текст файла/строки так, чтобы в целых числах разряды разделялись запятой. например:
454153 7842 45 456 7845.12 789,456:45:1234562 ах1000
454,153 784,2 45 456 7845.12 789,456:45:123,456,2 ах1000

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #5 : 04 Июня 2008, 18:03:11 »
хм забавно
а такая вещь спасет вас?
s/(\\d{3})(\\d)/\\1,\\2/g
убили кенни, сволочи

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #6 : 04 Июня 2008, 18:20:10 »
по всей видимости нет, вы можете привести точный листинг задачи?
убили кенни, сволочи

Оффлайн w01k

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 8
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #7 : 04 Июня 2008, 18:43:53 »
собственно говоря, всё уже написал:
все целые числа разделить запятыми на разряды слева направо. ответ представить в виде perl [-p -e -i] \'s/regexp/.../g\'

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #8 : 05 Июня 2008, 17:21:44 »
ну собственно говоря. что вы хотите?
провести операции с файлом или со строкой и для вас не важно каким способом главное чтобы целые числа разделить запятыми на разряды слева направо

или
вам нужно регулярное выражение которое бы сделало из исходной строки
454153 7842 45 456 7845.12 789,456:45:1234562 ах1000
результирующую
454,153 784,2 45 456 7845.12 789,456:45:123,456,2 ах1000

как бы если разделить сложную задачу на две простые станет все проще.

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

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #9 : 05 Июня 2008, 17:23:55 »
я к тому что не добавляйте лишних слов лишних сущностей. давайте для начала определим уровень абстракции. и проставим правильный акцент в задаче
убили кенни, сволочи

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #10 : 05 Июня 2008, 17:38:23 »
И в нахождении регулярного выражения у нас возникает проблема с первым и последним набором символов/*словом*/ в строке /* в предложении*/. Исходное выражение приходится модернизировать чтобы правильно найти слова в предложении придется к исходному выражению прибавить по пробелу с начала и с конца.

тогда можно будет написать регулярное выражение

s/[\\s|,|:]((\\d{3})(\\d+))[\\s|,|:]/\\2,\\3/g

мне кажется если в исходной строке вы сделаете выше описанные изменения то данное регулярное выражение и замена удовлетворят вашим условиям задачи
убили кенни, сволочи

Оффлайн w01k

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 8
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #11 : 05 Июня 2008, 23:53:15 »
Цитировать
ну собственно говоря. что вы хотите?
провести операции с файлом или со строкой и для вас не важно каким способом главное чтобы целые числа разделить запятыми на разряды слева направо

или
вам нужно регулярное выражение которое бы сделало из исходной строки
454153 7842 45 456 7845.12 789,456:45:1234562 ах1000
результирующую
454,153 784,2 45 456 7845.12 789,456:45:123,456,2 ах1000

строка - просто частность, пример различных комбинаций цифр.
Цитировать
s/[\\s|,|:]((\\d{3})(\\d+))[\\s|,|:]/\\2,\\3/g

эт всё не то.   во-первых, результирующая строка будет "съедать" пробелы/какие-либо разделители. во-вторых, отделится только первый разряд
 123456789
 123,456789 (а надо 123,456,789)

я, вроде, придумал регулярное выражение (парился дня 3, при том, что это было задание на 40 минут...)

s/([^\\w\\.]|\\.\\.|\\G)(\\d{3})(?=(\\d+\\.\\D+)|(\\d+\\s))/\\1\\2,/g

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #12 : 06 Июня 2008, 11:27:55 »
отличное регулярное выражение. объясните только необходимость
(\\d+\\.\\D+)| - я думаю что
s/([^\\w\\.]|\\.\\.|\\G)(\\d{3})(?=(\\d+\\s))/\\1\\2,/g
вполне хватет
убили кенни, сволочи

Оффлайн ravshaniy

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 191
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #13 : 06 Июня 2008, 12:07:43 »
и все таки это регулярное выражение не справилось с таким выражением
789345345345345456:45:1234562

предлагаю все же - гну свою линию:
s/(\\s|,|:|\\G)(\\d{3})(?=\\d+(\\s|,|:|\\G))/$1$2,/g;
« Последнее редактирование: 06 Июня 2008, 21:52:24 от ravshaniy »
убили кенни, сволочи

Оффлайн w01k

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 8
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
помогите придумать регулярное выражение
« Ответ #14 : 06 Июня 2008, 12:54:50 »
спасибо за придуманный пример.
Цитировать
объясните только необходимость
(\\d+\\.\\D+)|

это нужно для того, чтобы числа вида 1234.12323 не обрабатывались, т.к. они не целые.
Цитировать
предлагаю все же - гну свою линию:
s/(\\s|,|:|\\G)(\\d{3})(?=\\d+(\\s|,|:|\\G))/$1$2,/g;

кроме \\s, , и : цифры могут быть разделены кучей других символов - придётся все перечислить. к тому же бессмыслено ставить знак конца предыдущего совпадения \'\\G\' до и после шаблона.
вот выражение, которое справилось со строкой

789345345345345456:45:1234562

s/([^\\w\\.]|\\.\\.|\\G)(\\d{3})(?=(\\d+\\.\\D+)|(\\d+[^\\w\\.])|(\\d+\\Z))/\\1\\2,/g

789,345,345,345,345,456:45:123,456,2

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28