Разбор многострочного текста регулярными выражениями

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

viter.alex
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 221
Зарегистрирован: 27.07.2008 (Вс) 20:17
Откуда: Montreal

Разбор многострочного текста регулярными выражениями

Сообщение viter.alex » 02.02.2010 (Вт) 14:11

Имеется текстовый файл с таким содержимым:
Код: Выделить всё
5
+5169+15717
6
7
-28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
8
5
++1290
6
7
-28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
8
5

Это код для станка ЧПУ. Одна цифра в строке означает определённую команду. Если в строке есть знаки ±, то это перемещение по координатам. Мне нужно найти все блоки между командами 6,7 и 8,5. В приведённом примере таких блоков два:
Блок 1
Код: Выделить всё
6
7
-28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
8
5

Блок 2
Код: Выделить всё
6
7
-28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
8
5

Ищу таким выражением:
Код: Выделить всё
      Dim RegexObj As New Regex("^6$\r\n^7$\r\n([+\-\d\r\n]*?)^8$\r\n^5", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
      Dim MatchResults As Match = RegexObj.Match(ReadyCNC)

В переменной ReadyCNC хранится код. Но ничего не находит. В чём проблема? Регулярное выражение проверено в RegexBuddy
Лучше день потерять — потом за пять минут долететь!

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Разбор многострочного текста регулярными выражениями

Сообщение Antonariy » 02.02.2010 (Вт) 15:06

Проблема в переносах. Очень уж капризен этот Multiline. Рекомендую заменить переносы каким-нибудь символом.
Кроме того проблема в символе ^. Он означает, дословно, "Matches the beginning of input", а не line.
Лучший способ понять что-то самому — объяснить это другому.

viter.alex
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 221
Зарегистрирован: 27.07.2008 (Вс) 20:17
Откуда: Montreal

Re: Разбор многострочного текста регулярными выражениями

Сообщение viter.alex » 02.02.2010 (Вт) 15:49

Проблема была в ^: убрал его и всё получилось, хотя написано, что:
The match must start at the beginning of the string or line.

Переносы строк оставил
Лучше день потерять — потом за пять минут долететь!

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Разбор многострочного текста регулярными выражениями

Сообщение Antonariy » 02.02.2010 (Вт) 16:40

viter.alex писал(а):хотя написано, что:
Провокация, не иначе :)
Моя инфа из MSDN 2001 применительно к VBScript.Regexp.
Лучший способ понять что-то самому — объяснить это другому.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Разбор многострочного текста регулярными выражениями

Сообщение FireFenix » 02.02.2010 (Вт) 19:14

\s ?

в неё входит \r, \n, \t

чё-то бредовый способ обрезания.... не проще ли типа ([\s][\d]{1}[\s](.*?)[\s][\d]{1}[\s]) и собирать плоды из 2ой группы выборки ?

Antonariy писал(а):Проблема в переносах. Очень уж капризен этот Multiline. Рекомендую заменить переносы каким-нибудь символом.
Кроме того проблема в символе ^. Он означает, дословно, "Matches the beginning of input", а не line.

Вообще-то оно означает, что выбирается любой символ с начала строки
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

viter.alex
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 221
Зарегистрирован: 27.07.2008 (Вс) 20:17
Откуда: Montreal

Re: Разбор многострочного текста регулярными выражениями

Сообщение viter.alex » 02.02.2010 (Вт) 19:44

FireFenix писал(а):…не проще ли типа ([\s][\d]{1}[\s](.*?)[\s][\d]{1}[\s]) и собирать плоды из 2ой группы выборки ?…

Может и проще, но мне нужны только строки только между 6, 7 и 8, 5, а твой вариант найдёт всё
Лучше день потерять — потом за пять минут долететь!

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Разбор многострочного текста регулярными выражениями

Сообщение Antonariy » 02.02.2010 (Вт) 21:19

FireFenix писал(а):Вообще-то оно означает, что выбирается любой символ с начала строки
Ты собрался спорить с MSDN? Оно означает начало, во-первых, текста, а не строки (строк в тексте может быть много), а во-вторых, никакого не символа. Любой символ с начала строки это "(^|\r\n).".
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Разбор многострочного текста регулярными выражениями

Сообщение ANDLL » 02.02.2010 (Вт) 21:21

Ну вы блин даете.
Символы ^$ имею разные значения в зависимости от того установлен ли флажок Multiline.
Не знаю что ты там читал в MSDN
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Разбор многострочного текста регулярными выражениями

Сообщение FireFenix » 02.02.2010 (Вт) 21:38

^ - начало текста/строки
. - любой символ

^. - любой начальный символ

Antonariy писал(а):Любой символ с начала строки это "(^|\r\n).".

регулярка ниочём

Antonariy писал(а):Проблема в переносах. Очень уж капризен этот Multiline. Рекомендую заменить переносы каким-нибудь символом.

Просто надо понять как всё работает... тогда всё станет на свои места
Код: Выделить всё
m (PCRE_MULTILINE)
По умолчанию PCRE обрабатывает данные как однострочную символьную строку (даже если она содержит разделители строк). Метасимвол начала строки '^' соответствует только началу обрабатываемого текста, в то время как метасимвол "конец строки" '$' соответствует концу текста, либо позиции перед завершающим текст переводом строки (в случае, если модификатор D не установлен).

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

По умолчанию модификатор D всегда установлен

viter.alex писал(а):Может и проще, но мне нужны только строки только между 6, 7 и 8, 5, а твой вариант найдёт всё

ещё проще - 6[\s]+7[\s]+(.*?)[\s]+8[\s]+5

проверил на пхп:
Код: Выделить всё
<?php

$text= '5
+5169+15717
6
7
-28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
8
5
++1290
6
7
-28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
8
5';

$regex = '/6[\s]+7[\s]+(.*?)[\s]+8[\s]+5/ims';

preg_match_all($regex, $text, $match);

print_r($match[1]);

?>

результат
Код: Выделить всё
Array
(
    [0] => -28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
    [1] => -28+28
-5140+
++920
+114+
+185+185++185+
+1+115
+4540+
+-114
+185-185+185-+
+115-1
+-920
+28-28
)
Последний раз редактировалось FireFenix 02.02.2010 (Вт) 22:15, всего редактировалось 1 раз.
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Разбор многострочного текста регулярными выражениями

Сообщение iGrok » 02.02.2010 (Вт) 22:04

Проверил он на пхп..
Ты хоть сам-то видишь, что тебе за результат эта регулярка выдала?
Тебя там ничего не смущает?
label:
cli
jmp label

viter.alex
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 221
Зарегистрирован: 27.07.2008 (Вс) 20:17
Откуда: Montreal

Re: Разбор многострочного текста регулярными выражениями

Сообщение viter.alex » 02.02.2010 (Вт) 22:05

Да, результат не совсем тот, что нужно. Почему такие куцые фрагменты?

Я с первой регуляркой разобрался. Даёт то, что нужно.
Тут возник ещё один вопрос. Нужно из найденного фрагмента найти такие строки:
Код: Выделить всё
++\d
+-\d
+\d-
+\d+
-\d+
-\d-

т.е. строки, где в начале строки может быть + или - или они оба вместе, а за ними число. Если в начале строки стоят оба знака, то в конце знаков не будет, если в начале строки только один знак, то в конце строки обязательно будет тоже. Все возможные варинты я привёл.
Меня интересуют числа, в которых 5 и больше знаков. Сейчас ищу двумя регулярками:
"[+-]{1}(\d){5,}[+-]{1}\r\n" и "[+-]{2}(\d){5,}\r\n", но может можно свести до одной?
Лучше день потерять — потом за пять минут долететь!

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Разбор многострочного текста регулярными выражениями

Сообщение FireFenix » 02.02.2010 (Вт) 22:19

viter.alex писал(а):Да, результат не совсем тот, что нужно. Почему такие куцые фрагменты?

Протупил * выбирает {0, }, а нада + {1, }

P.S. поправил пример выше

viter.alex писал(а):Тут возник ещё один вопрос. Нужно из найденного фрагмента найти такие строки:
Код: Выделить всё
++\d
+-\d
+\d-
+\d+
-\d+
-\d-

т.е. строки, где в начале строки может быть + или - или они оба вместе, а за ними число. Если в начале строки стоят оба знака, то в конце знаков не будет, если в начале строки только один знак, то в конце строки обязательно будет тоже. Все возможные варинты я привёл.
Меня интересуют числа, в которых 5 и больше знаков. Сейчас ищу двумя регулярками:
"[+-]{1}(\d){5,}[+-]{1}\r\n" и "[+-]{2}(\d){5,}\r\n", но может можно свести до одной?

если не критично наличие + и -, то как вариант [+-]*([\d]{5,})[+-]*
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Разбор многострочного текста регулярными выражениями

Сообщение Antonariy » 03.02.2010 (Ср) 11:38

FireFenix писал(а):^ - начало текста/строки
. - любой символ

^. - любой начальный символ

Antonariy писал(а):Любой символ с начала строки это "(^|\r\n).".

регулярка ниочём
Ни о чем весь твой пост.

Чтобы внести полную ясность, ANDLL правильно заметил насчет поведения ^ при разных значениях multiline (о чем в MSDN 2001 нет ни слова). Если оно true, то "^." это действительно первый символ каждой строки, если же false, то она вернет один первый символ. А моя регулярка вернет первый символ любой строки при любом значении multiline. Правда вместе с переносами, но это можно решить дополнительными скобками — "(^|\r\n)(.)".
Лучший способ понять что-то самому — объяснить это другому.

viter.alex
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 221
Зарегистрирован: 27.07.2008 (Вс) 20:17
Откуда: Montreal

Re: Разбор многострочного текста регулярными выражениями

Сообщение viter.alex » 03.02.2010 (Ср) 15:17

Господа, мой вопрос решён. Спасибо большое.
прошу обратить внимание на мой второй вопрос в этой же ветке. Если необходимо, я его перенесу в новую.
Сейчас я ищу фрагменты между 6,7 и 8,5, а затем внутри каждого такого фрагмента ищу одно число, в котором не менее 5 цифр. Число в строке может иметь два знака впереди или один знак впереди, а другой сзади. Я это уже объяснял.
Но получается очень неудобно, потому что строки, где такое число найдено, мне нужно заменить своим текстом. Мне пришла в голову идея сразу искать числа с не менее, чем пятью цифрами; ставить в начале этой строки какие-нибудь отличительные символы, а затем, уже вторым поиском, производить нужную мне замену.
Но не допру как искать.
Лучше день потерять — потом за пять минут долететь!

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Разбор многострочного текста регулярными выражениями

Сообщение Nord777 » 03.02.2010 (Ср) 19:49

Сейчас ищу двумя регулярками:
"[+-]{1}(\d){5,}[+-]{1}\r\n" и "[+-]{2}(\d){5,}\r\n", но может можно свести до одной?
Пойдет \+[+-]\d+|[+-]\d+[+-] :?:
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

viter.alex
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 221
Зарегистрирован: 27.07.2008 (Вс) 20:17
Откуда: Montreal

Re: Разбор многострочного текста регулярными выражениями

Сообщение viter.alex » 03.02.2010 (Ср) 20:17

Забыл про "или": | :(
Вот так совсем хорошо, можно обойтись и без "или":
^[+-]{1,2}(\d{5,})[+-]?\r\n
А как же теперь всё сделать одним заходом? Как искать это выражение, только если оно находится между 6,7 и 8,5
Пытаюсь писать так:
6\r\n7\r\n.*^[+-]{1,2}(\d{5,})[+-]?\r\n
но вообще ничего не ищет
Лучше день потерять — потом за пять минут долететь!

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Разбор многострочного текста регулярными выражениями

Сообщение Nord777 » 03.02.2010 (Ср) 20:52

Не нужно пытаться запихнуть весь код в одну строку.
На форме одна кнопка и два текстовых поля.
В первом поле исходный текст. Во втором - измененный.
Код: Выделить всё
   Private Rgx1 As New Regex("^6\r\n^7(.*\r\n)+?^8\r\n^5", RegexOptions.Multiline)
   Private Rgx2 As New Regex("\+[+-]\d+|[+-]\d+[+-]")


   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      Dim Start, Length As Integer
      Dim SB As New StringBuilder

      For Each M As Match In Rgx1.Matches(TextBox1.Text)
         Length = M.Index - Start
         SB.Append(TextBox1.Text, Start, Length)
         SB.Append(Rgx2.Replace(M.Value, AddressOf MatchEvaluator))
         Start = M.Index + M.Length
      Next
      TextBox2.Text = SB.ToString
   End Sub


   Private Function MatchEvaluator(ByVal match As System.Text.RegularExpressions.Match) As String
      Static Num As Integer = 0
      Num += 1
      Return "[Match" & Num.ToString & "]"
   End Function
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

viter.alex
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 221
Зарегистрирован: 27.07.2008 (Вс) 20:17
Откуда: Montreal

Re: Разбор многострочного текста регулярными выражениями

Сообщение viter.alex » 04.02.2010 (Чт) 10:01

Nord777, вот этого MatchEvaluator как раз и не хватало! То, что нужно!
Лучше день потерять — потом за пять минут долететь!


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14

    TopList