Что нового

[RegExp] Применение условного оператора в регулярном выражении

IgRo

Знающий
Сообщения
65
Репутация
5
RexExp с условным оператором
если '-00' или '_000' или '_00' то "" иначе как есть
'АБВГ 123.456.789-01' -> 'АБВГ.123456.789-01'
'АБВГ.123456.789-00' -> 'АБВГ.123456.789'
'АБВГ.123 456.789_00' -> 'АБВГ.123456.789'
'АБВГ.123456.789_000' -> 'АБВГ.123456.789'
Пытаюсь так:
Код:
;$sText='АБВГ.123456.789'
$sText='АБВГ 123.456.789-00'
$sPatOB='([А-Я]{4})(?:\s?\.?)(\d{3})(?:\s?\.?)(\d{3})(?:\s?\.?)(\d{3})'
$sPatISP='([\-_][0-9\/]{1,3})?'
$sPat=$sPatOB&$sPatISP
$sRep="$1.$2$3.$4$5"
if StringRegExp($sText,$sPat,0) then
			$aResult = StringRegExpReplace($sText, $sPat, $sRep)
			ConsoleWrite($aResult)
EndIf

на выходе "АБВГ.123456.789-00" :scratch:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Re: [RegExp] Условие в RegExp

IgRo
? Может будет проще составить выражение, если сперва удалить все пробелы и точки, и поменять все _ на -
С таким будет проще:
АБВГ123456789-000
 
Автор
I

IgRo

Знающий
Сообщения
65
Репутация
5
Re: [RegExp] Условие в RegExp

Вопрос с пробелами и точками решается группой (?:\s?\.?)
или универсальнее (?:[ .]{,2}) т.к. был случай когда пользователь вводил и так "АБВГ .123 456. 789" но это случай "клинический" :smile:
Не решается вот это
если '-00' или '_000' то ""
В RexExp есть конструкция вида
(?(условие)шаблон-да|шаблон-нет) или (?(условие)шаблон-да)
но как применить её немогу понять :stars:
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Re: [RegExp] Условие в RegExp

IgRo [?]
но как её прикрутить не могу понять

(_000)(?(1)$|)
Например:
Если найдена первая група, то искать разрыв строки, иначе... тут не указано.

condition - может быть любым выражением, не обязательно группы захвата.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: [RegExp] Условие в RegExp

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"[RegExp] Условие в RegExp" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Глобальный модератор.










т.к. 100% тем относится к этой категории в этом разделе
 
Автор
I

IgRo

Знающий
Сообщения
65
Репутация
5
Re: [RegExp] Условие в RegExp

Kaster :shok:
"(?(condition)yes-pattern|no-pattern)" не видел чтобы обсуждалась
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: [RegExp] Условие в RegExp

IgRo
ты читал предупреждение?
 
Автор
I

IgRo

Знающий
Сообщения
65
Репутация
5
Если ([\-_][0]{1,3}) то () иначе ([\-_][0-9\/]{1,3})
Код:
$sText='-00' ;'-0', '_000'
$sPat='(?([\-_][0]{1,3})()|([\-_][0-9\/]{1,3}))'
$sRep='$1'
$aResult = StringRegExpReplace($sText, $sPat, $sRep)
ConsoleWrite($aResult & @CRLF)

Выдает '-00' ожидаемый результат ''
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
IgRo
Я пока не нашёл применение этого оператора. Разве что быть модным. Итак
(?(condition)yes-pattern|no-pattern)
Например, если "ка" то дописываем "ртошка" иначе "банан". С таким же успехом я могу написать (картошка|банан).
Вот здесь пример с использованием, но я вполне далее написал без него.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Блин! Вместо того чтобы скопировать текст кликнул в "Отметить сообщение полезным" ...
Оно бесполезное! Этот скрипт вообще ничего не фильтрует, в качестве результата он выдаёт абсолютно ВСЕ строки которые подаются ему на вход (для тестов брал все примеры из 1-го сообщения)
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
Код:
Local $a[4] = [ _
'АБВГ 123.456.789-01', _
'АБВГ.123456.789-00', _
'АБВГ.123 456.789_00', _
'АБВГ.123456.789_000']

$sOut = ''
For $i = 0 To 3
	; $sOut &= StringRegExpReplace($a[$i], '^([А-Я]{4})(?:[\h.])?(\d{3})(?:[\h.])?(\d{3})(?:[\h.])?(\d{3})(_000?|-00)$', '\1\2\3\4\5') &@LF
	$tmp = StringRegExpReplace($a[$i], '^([А-Я]{4})(?:[\h.])?(\d{3})(?:[\h.])?(\d{3})(?:[\h.])?(\d{3}[_-]\d+)$', '\1.\2\3.\4')
	$tmp = StringRegExpReplace($tmp, '(_000?|-00)$', '')
	$sOut &= $tmp &@LF
Next

MsgBox(0, 'Сообщение', $sOut)
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
AZJIO
та в два прохода я тоже сделал
Код:
Dim $aText[7] = ['АБВГ123456.789', 'АБВГ 123.456.789-01', 'АБВГ.123456.789-00', 'АБВГ.123 456.789_00', 'АБВГ.123456.789_000', 'АБВГ.123456.789_0/2', 'АБВГ.123456.789_3']
$sPatOB='([А-Я]{4})(?:\s?\.?)(\d{3})(?:\s?\.?)(\d{3})(?:\s?\.?)(\d{3})'
$sPatISP='([\-_][0-9\/]{1,3})?'
$sPat=$sPatOB&$sPatISP
$sRep="$1.$2$3.$4$5"
For $i=0 To UBound($aText)-1
	$sText = $aText[$i]
	if StringRegExp($sText,$sPat,0) then
		$sText1 = StringRegExpReplace($sText, "([\-_]0{2,})", "")
		$aResult = StringRegExpReplace($sText1, $sPat, $sRep)
		ConsoleWrite($aResult&@CRLF)
	EndIf
Next


Но я так понимаю что ТС хочет всё в одно выражение запихнуть.
Третий день разбираюсь с этими ненавистными регулярными выражениями
OffTopic:
я так думаю что когда программистов расплодилось слишком много, то кому-то пришла в голову мысль создать среди них секту продвинутых мыслителей. Вот так, по-моему, и появились регулярные выражения...

и чего-то думаю что не получится в одно выражение. Как ни странно наибольшие трудности вызывают '-' и '_', а именно то что в определённых случаях их не только нужно заменить, но и вообще убрать.
imho, данная задача имеет чисто академический интерес. На практике спокойно можно сделать не одно StringRegExpReplace, а два и не буксовать на этом вопросе.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
C2H5OH [?]
OffTopicя так думаю что когда программистов расплодилось слишком много, то кому-то пришла в голову мысль создать среди них секту продвинутых мыслителей. Вот так, по-моему, и появились регулярные выражения...
а как обрабатывать тексты переменного содержания без регулярных выражений? :scratch:
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
а как обрабатывать тексты переменного содержания без регулярных выражений?
Ммм, как-то не сталкивался по-взрослому с обработкой текстов... :-[
Поэтому и не понимаю - существует ли проблема впихнуть всё решение в ОДНО регулярное выражение, или можно обойтись несколькими последовательными?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
C2H5OH [?]
не понимаю - существует ли проблема впихнуть всё решение в ОДНО регулярное выражение,
не всегда. по крайней мере в AutoIt. да и потом, когда дело касается обработки текстов очень редко приходится задумываться над таким. хоть 2 хоть 10 выражений. узкое место всегда будет в другом. только если твой текст не гигабайтовый. но тогда надо совершенно по другому походить к вопросу
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
C2H5OH [?]
Как ни странно наибольшие трудности вызывают '-' и '_', а именно то что в определённых случаях их не только нужно заменить, но и вообще убрать.

Тут можно сделать так. Добавив это выражение в конец паттерна
(?:-00|_0{2,3}|(.*))$
А замену расширить до следующей группы, например если уже есть 3 группы захвата, то добавить 4. Как то так:
\1.\2.\3\4
Тогда это будет работать так:
При наличии в конце -00 или _00 или _000 группа захвата не будет образовываться и вместо \4 будет пустота, что равносильно удалению. А иначе, сработает третье условие или, и в (.*) попадает все до конца строки - оно же будет в \4.
 
Автор
I

IgRo

Знающий
Сообщения
65
Репутация
5
inververs
Именно так
При наличии в конце -00 или _00 или _000 группа захвата подлежит удалению
Часть задачи с большой помощью всех откликнувшихся решил так
Код:
Dim $aText[8] = [ _
'АБВГ123456 .789 ', _
'АБВГ 123.456.789-01', _
'АБВГ.123456.789-00', _
'АБВГ.123 456.789_00', _
'АБВГ.123.456. 789_000', _
'АБВГ.123456.789_0002', _
'АБВГ.123456.789_0/2', _
'АБВГ.123..456.789_3']
$sDelim='(?:\s?\.?\s?\.?)' ;  '. ', '..' ,' .', ' '
$sPatOB='([А-Я]{4})'&$sDelim&'(\d{3})'&$sDelim&'(\d{3})'&$sDelim&'(\d{3})'
$sPatISP='(?:[\-_]0+$|\s)?([\-_][0-9\/]+$|\s)?'
$sPat=$sPatOB&$sPatISP
$sRep="$1.$2$3.$4$5"
$sFormat="%-22s->  %-22s"
For $i=0 To UBound($aText)-1
    $sText = $aText[$i]
    $aResult = StringRegExpReplace($sText, $sPat, $sRep)
    ConsoleWrite(StringFormat($sFormat,$sText,$aResult)& @CRLF)
Next



Добавлено:
Сообщение автоматически объединено:

Не решена
наибольшие трудности вызывают '-' и '_', а именно то что в определённых случаях их не только нужно заменить, но и вообще убрать.
т.е. на выходе в $5 вместо '_' получить '-' наверное как-то с (?=[\-_])

Посоветуйте название темы т.к. решение не удалось с помощью (?(condition)yes-pattern|no-pattern) "Применения условного оператора в регулярном выражении"
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
IgRo
(?:\s?\.?\s?\.?) можно записать так (?:[.\h]+)
\s - включает переносы строк, не думаю что там где горизонтальные пробелы стоит использовать и вертикальные.
[\-_] так короче [_-]
И вариант от inververs кажется более читабельным
а так же если 123456 может не содержать точки, а после $sDelim не используется "?" то легко предположить что интерпретация уже не верна или запутана.
Форматированную строку поправил табами
Код:
Local $aText[8] = [ _
		'АБВГ123456 .789 ', _
		'АБВГ 123.456.789-01', _
		'АБВГ.123456.789-00', _
		'АБВГ.123 456.789_00', _
		'АБВГ.123.456. 789_000', _
		'АБВГ.123456.789_0002', _
		'АБВГ.123456.789_0/2', _
		'АБВГ.123..456.789_3']
$sDelim = '(?:[.\h]+)' ;  '. ', '..' ,' .', ' '
$sPatOB = '([А-Я]{4})' & $sDelim & '(\d{3})' & $sDelim & '?(\d{3})' & $sDelim & '(\d{3})'
$sPatISP = '(?:[_-]0+|(.*))$'
$sPat = $sPatOB & $sPatISP
$sRep = "$1.$2$3.$4$5"
$sFormat = "%-22s\t->\t%-22s"
For $i = 0 To UBound($aText) - 1
	$sText = $aText[$i]
	$aResult = StringRegExpReplace($sText, $sPat, $sRep)
	ConsoleWrite(StringFormat($sFormat, $sText, $aResult) & @CRLF)
Next
 
Верх