![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: нет Всего: 6 |
Добрейшего времени суток, друзья.
Столкнулся со следующей проблемой: Имеем следующую теорию Alternation Constructs, пытаюсь использовать '(?(expression)yes|no)' регулярное выражение. Входной текст: "abcdefg", пишу (?(abc)defg|"") - получаю 'No Matches' (конструктор регулярных выражений 'RAD Software Regular Expression Designer 1.4.7'). Если кто-нибудь сталкивался с подобным или знает в чем дело, помогите, пожалуйста. |
|||
|
||||
| Bishop |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 3.6.2005 Где: Минск, Беларусь Репутация: 6 Всего: 16 |
FiMa1,
Вы хотите "abc" использовать как шаблон, а оно воспринимается как name. Укажите явно: (?(?<=abc)defg|""). Grouping Constructs. Синтаксис шаблонов — разделы Утверждения и Условные подмаски. |
|||
|
||||
| FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: нет Всего: 6 |
Bishop, большое спасибо! Я пробежался глазами по приведенным ссылкам, пока не уяснил для себя, что можно считать "именем"? Никогда до этого сталкивался с этим понятием. (?(name)yes|no) Matches the "yes" part if the named capture string has a match; otherwise, matches the "no" part. The "no" part can be omitted. If the given name does not correspond to the name or number of a capturing group used in this expression, the alternation construct is interpreted as an expression test (described in the preceding row of this table). Не подскажите вкратце, если есть минутка. Был бы еще больше признателен Это сообщение отредактировал(а) FiMa1 - 28.8.2008, 16:46 |
|||
|
||||
| Bishop |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 3.6.2005 Где: Минск, Беларусь Репутация: 6 Всего: 16 |
FiMa1, группы (подмаски), т.е. выражения в скобках можно именовать, тогда к ним можно будет обращаться не по номерам, а по этим именам.
В случае альтернатив:
И это наиболее понятный способ их использования. Я похоже ошибся в прошлом посте:
Т.е. все работает, но анализ идет четко с начала строки, как будто там не abc, а ^abc.
А этот результат объяснить не могу |
||||||||
|
|||||||||
| source777 |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1878 Регистрация: 12.3.2007 Репутация: 4 Всего: 56 |
В этом посте ты тоже к сожалению ошибся, это заметно, например, на таком примере:
Т.е. во всех 3 нижних строках кода из твоего поста фактически срабатывает условие "no", но срабатывает как-то глючно, в чём ты впрочем не виноват -------------------- Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте |
||||
|
|||||
| Bishop |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 3.6.2005 Где: Минск, Беларусь Репутация: 6 Всего: 16 |
source777,
В первой из трёх нижних строк выполняется yes. А в остальных всё тоже правильно, то есть не "глючно"
Я почему-то подумал (и похоже, ты тоже), что эта конструкция работает по логике if-then-else: если expression истинно, то ищется шаблон yes, иначе шаблон no. Но это не так. Выражение "yes" — это вся часть (expression)yes. А (expression), если не указано явно, это (?=expression). Фактически, это сокращенная запись, которую можно развернуть в:
И тогда все ясно с примерами: Место (abc) === (?=abc) в строке находится "(_здесь_)abcdefgh"
Потому что:
|
||||||||
|
|||||||||
| FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: нет Всего: 6 |
Bishop, source777, большое спасибо за участие! Теперь понятно с именами и почему я с ними не сталкивался, я не использовал регулярные выражения непосредственно в коде на C#.
|
|||
|
||||
| source777 |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1878 Регистрация: 12.3.2007 Репутация: 4 Всего: 56 |
Однако, всё равно остались невыясненные моменты, например,
Казалось бы, поскольку IsMatch == true, то в Match.Value всегда должно быть "yes", в независимости от "no" - части, однако это не так... Причём если использовать в качестве входной строки "yesno", то так и будет, однако такая жёсткая привязка в началу строки не всегда подходит, в качестве воркэраунда насколько я выяснил сработает:
-------------------- Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте |
||||||
|
|||||||
| Bishop |
|
||||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 3.6.2005 Где: Минск, Беларусь Репутация: 6 Всего: 16 |
source777,
Не, не так. Оно не ищет условие, идет последовательный анализ строки и, если условие ложно, а часть NO в этой позиции находит совпадение, разбор прекращается. Смотри:
Причем (yes) это сокращенная запись утверждения (?=yes). Разбор начинается с начала строки: на символе "a" (?=yes) ложно — переход к части NO; .* в этой позиции совпадает со всей строкой — это результат.
Здесь разбор идет так: "a" — (?=yes) ложно, часть NO в текущей позиции не совпадает; "b" — тоже; "c" — тоже; "y" — (?=yes) истинно, (?=yes)yes совпадает — это результат. И правильный вариант:
Этапы разбора: "a" — (?=.*yes) истинно, но (?=.*yes)yes не совпадает, .* пропускается; "b" — тоже; "c" — тоже; "y" — (?=.*yes) истинно, (?=.*yes)yes совпадает — это результат. Тогда всё ясно с непонятным результатом выражения из моего позапрошлого поста:
Разбор: "a" — (?=abc) истинно, но (?=abc)f не совпадает, .* пропускается; "b" — (?=abc) ложно, .* совпадает с "bcdefgh" — это результат. Не вся строка, т.к. "a" уже пропущена, а разбор без особой нужды в обратную сторону не идёт. Может я ошибаюсь на счёт внутренней работы regex engine, но концептуально оно вот так. Т.е. не ищется совпадение expression по всей строке (как мы думали), оно вычисляется на общих основаниях по мере разбора строки. От простой альтернативы отличается тем, что пока условие истинно совпадения в блоке NO не ищутся. Вот:
В описании этапов под буквами подразумеваются Zero-width позиции перед ними. Пытался объяснить, надеюсь не запутал ещё больше Это сообщение отредактировал(а) Bishop - 29.8.2008, 19:53 |
||||||||||||
|
|||||||||||||
| source777 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1878 Регистрация: 12.3.2007 Репутация: 4 Всего: 56 |
Bishop, спасибо, более менее прояснилась ситуация
-------------------- Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |