Модераторы: diadiavova, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
>  Заключение частей строки в теги. С помощью регулярных выражений. 
V
    Опции темы
asj
Дата 26.11.2011, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



Есть набор строк типа:

Word [abc]
.Any word...
Word [abc] a [a[bc]] bc [a[bc]d]
...
нужно их завернуть в теги. значение имеют первое слово в каждой строке, квадратные скобки, точка первым символом. Вывод должен получиться такой

[tag1]Word[/tag1] [tag2][abc][/tag2]
[tag3].Any word...[/tag3]
[tag1]Word[/tag] [tag2][abc][/tag2] a [tag2][a[bc]][/tag2] bc [tag2][a[bc]d][/tag2]

1) первое слово строк оборачивается в теги [tag1]Word [/tag1]
2) если первый символ в строке точка, то вся строка без изменений внутри оборачивается в др. тег [tag3]
3) ну и символы в квадратных скобках тоже оборачиваются тегом, причем внутри одних кв. скобок могут быть и другие, нужно обернуть их одним блоком типа  [tag2][a[bc]][/tag2]

я поковырял и слепил для 1): (вроде пашет)
Src = Regex.Replace(Src, "\n(\s*)([A-Za-z0-9]+)", "$1[tag1]$2[/tag1]")
для 2): (вроде тоже, но [/tag3] пихает на новую строку, пробовал указать $ в кач.ве конца строки не хочет его хавать)
Src = Regex.Replace(Src, "(\..*\r)", "[tag3]$1[/tag3]")
для 3) в случае одиночных скобок сделал, но с вложенными вообще ниче не выходит...

Помогите правильно составить паттерны для таких замен? до этого приходилось играться с регулярками на элементарном уровне... заранее спасибо.
PM MAIL   Вверх
diadiavova
Дата 26.11.2011, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



asj, Пара уточнений:
1. Набор строк представляет из себя один текст или они у тебя в программе являются разными объектами? 
2. Если строка начинается с точки, то ее всю надо заключить в один тег, не взирая на возможное наличие квадратных скобок?


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
asj
Дата 26.11.2011, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



Цитата(diadiavova)
Набор строк представляет из себя один текст или они у тебя в программе являются разными объектами? 
этот набор строк один текст. Если хотите аналогию, то считайте что это кусок html-кода которому нужно сделать "подсветку" синтаксиса тегами.
Цитата(diadiavova)
 Если строка начинается с точки, то ее всю надо заключить в один тег, не взирая на возможное наличие квадратных скобок?
да, если первый символ точка, то невзирая ни на что другое, всю строку целиком в отдельный тег в неизменном виде.


Это сообщение отредактировал(а) asj - 26.11.2011, 14:42
PM MAIL   Вверх
diadiavova
Дата 26.11.2011, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(asj @  26.11.2011,  15:41 Найти цитируемый пост)
да, если первый символ точка, то невзирая ни на что другое, всю строку целиком в отдельный тег в неизменном виде.

Тогда еще один момент: под первым символом подразумевается первый символ в строке и заключать в тег надо все, вплоть до окончания строки? То есть текст поделен на строки и можно анализировать каждую строку отдельно? А если нет, то каковы признаки начала и конца, к примеру строки с точкой. Ну то есть, если попадется строка типа
Код

abc.def[gh]

Как это должно выглядеть на выход: так
Код

[tag1]abc[/tag1][tag3].def[gh][/tag3]

или так
Код

[tag1]abc[/tag1][tag3].def[/tag3][tag2][gh][/tag2]
Или например так?
Код

[tag1]abc.def[/tag1][tag2][gh][/tag2]


Это сообщение отредактировал(а) diadiavova - 26.11.2011, 14:57


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
diadiavova
Дата 26.11.2011, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Относительно примера с вложенными квадратными скобками вот
Код

Imports System.Text.RegularExpressions

Module Module1
    Dim re As New Regex("((?<brop>\[).*?(?<brcl-brop>\]))|[^\[\]]*")
    Sub Main()
        Dim input = "Word [abc] a [a[bc]] bc [a[bc]d]"
        For Each m As Match In re.Matches(input)
            Console.WriteLine(m.Value)
        Next
        Console.ReadLine()
    End Sub

End Module


Если под строкой, начинающейся с точки, подразумевается действительно строка текста(то есть она заканчивается символами vbNewLine), то можно разбирать весь текст вообще построчно и если строка начинается с точки, то ее можно заключить в нужные теги безо всяких регулярок.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
asj
Дата 26.11.2011, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



Цитата(diadiavova)
То есть текст поделен на строки и можно анализировать каждую строку отдельно?

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

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

[tag3].def[gh]
[/tag3][tag1]Word[/tag1]

структура строк должна сохраняться, т.е. 

[tag3].def[gh][/tag3]
[tag1]Word[/tag1]

иначе можно напороть всякого...

Цитата(diadiavova)
Ну то есть, если попадется строка типа

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



PM MAIL   Вверх
asj
Дата 26.11.2011, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



Цитата(diadiavova)
Относительно примера с вложенными квадратными скобками вот


одиночные скобки берет корректно, а в составных забывает последнюю:

Word 
[abc]
 a 
[a[bc]

 bc 
[a[bc]
d

тогда уж:

Word 
[abc]
 a 
[a[bc]]

 bc 
[a[bc]d]

Добавлено через 9 минут и 9 секунд
p.s: а вообще я чтото не знаю, как красиво должен выглядеть построчный анализ текста с регуляркой, и эффективно ли это мучает вопрос.
Я пробую мутить сразу, с заменой во всем обьеме текста:

Src = Regex.Replace(Src, "", "")
Src = Regex.Replace(Src, "", "")
...
так каждым паттерном. Пробовал намутить (скобки) со String.Replace но результаты "смешения" итогов такой замены с итогом работы регулярок не убедили, поэтому решил Regex сочинять...
PM MAIL   Вверх
diadiavova
Дата 26.11.2011, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



asj, попробуй так, вроде работает
Код

Imports System.Text.RegularExpressions
Module Module1
    Dim re As New Regex("((?<brop>\[)[^\[\]]*)+([^\[\]]*(?<brcl-brop>\]))+|[^\[\]]*")

    Sub Main()
        Dim input = "Word [abc] a [a[bc]] bc [a[bc]d]"
        Console.WriteLine(input)
        For Each m As Match In re.Matches(input)
            Console.WriteLine(m.Value)
        Next
        Console.ReadKey()
    End Sub
End Module

Выдает вот что
Код

Word [abc] a [a[bc]] bc [a[bc]d]
Word
[abc]
 a
[a[bc]]
 bc
[a[bc]d]
Я так понимаю, ты именно этого добиваешься

Добавлено через 4 минуты и 40 секунд
Цитата(asj @  26.11.2011,  16:52 Найти цитируемый пост)
p.s: а вообще я чтото не знаю, как красиво должен выглядеть построчный анализ текста с регуляркой

Разбиваешь текст на строки и обходишь каждую регуляркой
Цитата(asj @  26.11.2011,  16:52 Найти цитируемый пост)
 и эффективно ли это мучает вопрос.

На до тестировать(если речь о производительности). На небольших текстах в любом случае расход ресурсов будет небольшим.
Цитата(asj @  26.11.2011,  16:52 Найти цитируемый пост)
Я пробую мутить сразу, с заменой во всем обьеме текста:

Можно разделять все разные конструкции вертикальной чертой и объединять в именованные группы, после чего обходить найденные совпадения и проверять наличие той или иной группы. Звучит сложно, но для сложных примеров это лучшее решение ИМХО.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
asj
Дата 27.11.2011, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



Цитата(diadiavova)
Можно разделять все разные конструкции вертикальной чертой и объединять в именованные группы
это интересно... блин, к сожалению я сейчас просто не в силах затратить нужное кол-во времени чтобы раскрыть тему регулярок (
Цитата(diadiavova)
Я так понимаю, ты именно этого добиваешься

ага, но нужны только совпадения со скобками, их потом заменить же надо.
Цитата(diadiavova)
Разбиваешь текст на строки и обходишь каждую регуляркой

ну ладно, постараюсь и так попробовать... 

PM MAIL   Вверх
diadiavova
Дата 27.11.2011, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(asj @  27.11.2011,  11:23 Найти цитируемый пост)
ага, но нужны только совпадения со скобками, их потом заменить же надо.

Ну так это еще проще: удали из моей регулярки все, начиная с вертикальной черты. Я из первого поста понял, что надо и все остальное тоже отлавливать. А заменить ведь не проблема, посмотри перегрузку метода реплейс, где надо в качестве замены передавать делегат. Там просто надо будет написать функцию, которая проверяет, что заменяет, после чего возвращает строку замены.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
diadiavova
Дата 27.11.2011, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Код

Imports System.Text
Imports System.Text.RegularExpressions

Module Module1
    Dim re As New Regex("(?<nl>\r\n)|(?<=\n)(?<dot>\.[^\n\r]*)|(?<br>((?<brop>\[)[^\[\]\n\r]*)+([^\[\]\n\r]*(?<brcl-brop>\]))+)|(?<txt>[^\[\]\n\r]*)", RegexOptions.Multiline)
    Sub Main()
        Dim builder As New StringBuilder
        With builder
            .AppendLine("Word[abc]")
            .AppendLine(".Any word...")
            .AppendLine("Word [abc] a [a[bc]] bc [a[bc]d]")
        End With

        Dim input = builder.ToString

        Console.WriteLine("Входная строка:")
        Console.WriteLine()
        Console.WriteLine(input)
        Console.WriteLine()
        Console.WriteLine()
        Console.WriteLine("Результат:")
        Console.WriteLine()

        Dim replacefunc =
            Function(m As Match) As String
                If m.Groups("dot").Success Then
                    Return String.Format("[tag3]{0}[/tag3]", m.Groups("dot").Value)
                ElseIf m.Groups("br").Success Then
                    Return String.Format("[tag2]{0}[/tag2]", m.Groups("br").Value)
                ElseIf m.Groups("txt").Success Then
                    Return String.Format("[tag1]{0}[/tag1]", m.Groups("txt").Value)
                ElseIf m.Groups("nl").Success Then
                    Return vbNewLine
                End If
                Return ""
            End Function

        Console.WriteLine(re.Replace(input, replacefunc))
        Console.ReadKey()
    End Sub

End Module




--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
asj
Дата 27.11.2011, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



ага спасибо, код мне читабельнее чем слова )
вроде все ясно, если что не получится в итоге, я еще спрошу, ок?
PM MAIL   Вверх
asj
Дата 27.11.2011, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



такс... а в результате такого подхода я не вижу как сделать чтобы замена 
[tag1]Word[/tag1] работала только один раз (паттерн править?) ((
Цитата(asj)
1) первое слово строк оборачивается в теги [tag1]Word[/tag1]

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


Это сообщение отредактировал(а) asj - 27.11.2011, 17:00
PM MAIL   Вверх
diadiavova
Дата 27.11.2011, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(asj @  27.11.2011,  17:58 Найти цитируемый пост)
такс... а в результате такого подхода я не вижу как сделать чтобы замена 
[tag1]Word[/tag1] работала только один раз 

Да так же как и с точкой, просто вот такую финтифлюшку поставь перед группой txt
Код

(?<=\n)



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
asj
Дата 29.11.2011, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.11.2011

Репутация: нет
Всего: нет



поменял для Word в шаблоне вместо \n\r поставил \s (слово же до пробела идет иначе в тег попадал мусор например кавычки "):
[tag1]Word "[/tag1]
добавил еще один тег и группу. но теперь остался последний вопрос - слова Word могут начинаться не с начала строки а с пробела(ов), ну короче с пустого места неизвестной длины (может и таб хотя нет вряд ли). после моей переделки с \s слово в этом случае не попадает в теги (( 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума VB .NET
diadiavova
  • Прежде чем задать вопрос, воспользуйтесь поиском: возможно Ваш вопрос уже обсуждался и на него был получен ответ.
  • Если такой же вопрос не найден, не стоит задавать свой вопрос в любую тему, создайте новую.
  • Заголовок темы должен отображать ее суть.
  • Содержание поста должно описывать проблему понятно, но в то же время, по возможности, лаконично. Сначала следует описать суть вопроса, потом можно привести пример кода, не вынуждайте других участников угадывать в чем Ваша проблема - телепатов здесь нет.
  • Будьте взаимно вежливы и дружелюбны.
  • При оформлении сообщений используйте форматирование, примеры кода заключайте в теги [CODE=vbnet][/CODE].
  • Также ознакомьтесь с общими правилами, действующими на всем форуме.
  • Если вопрос решен, не забывайте помечать тему решенной(вверху темы есть ссылка). Кроме того, если Вы хотите отблагодарить участников, оказавших помощь в решении, можно повысить им репутацию, в случае, если у Вас менее 100 сообщений в форуме и функция изменения репутации Вам недоступна, можете написать сюда.
  • Общие вопросы по программированию на платформе .NET обсуждаются здесь.
  • Литература по VB .NET обсуждается здесь.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, diadiavova.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | VB .NET | Следующая тема »


 




[ Время генерации скрипта: 0.0687 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.