Что нового

[RegExp] Обобщенная идентификация комплексного числа

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Гуру регэкспов (не будем тыкать пальцАми) :smile:
Подскажите, как можно посредством регулярных выражений распознать является ли строка условным комплексным числом.
Поясняю:
Комплексное число - это пара действительных чисел, алгебраическая запись которых может быть представлена в виде
Код:
z = a + bi
где i - это мнимая единица (всегда обозначается как i)
Мне бы хотелось, чтобы скрипт мог распознавать подобные числа.
Например
5[,.]1 + 2[,.]1[*_x][ij] - да
5[,.] + 2[,.][*_x][ij] - да
5 + 2[*_x][ij] - да
5 + 2[ij] - да
[a-z] + ... - нет
... + [a-z]... - нет
присутствие любых символов кроме цифр, точки/запятой (как разделитель целой и дробной части), знаков *, _, х (разделитель мнимой части от мнимой единицы) - нет
Для этих целей я соорудил следующую конструкцию
Код:
$a = '  5  . 1 + 2,4 * j   '; Исходная строка
$b = StringRegExpReplace($a, '\s', ''); Удаляем все пробелы
$pattern = '\d+[\.,\d*]?[^\.]?\+\d+[\.,]?\d*[_\*x][ij]'; Паттерн
If StringRegExp($b, $pat) Then
	$c = StringReplace($b, ',', '.'); Заменяем все запятые, если есть, на точки
	$d = StringRegExpReplace($c, '[x\*_]', ''); Удаляем все разделители мнимой части, если есть
	$e = StringRegExpReplace($d, '\.\+', '+'); Если есть точки без дробной части, удаляем такие точки
	$f = StringRegExpReplace($e, 'j', 'i'); Заменяем j на i (если был задан такой формат мнимой единицы)
	MsgBox(0, '', $b & @CRLF & $c & @CRLF & $d & @CRLF & $e & @CRLF & $f); Вывод результата на экран
Else
	MsgBox(0, '', 'Nope'); Если строка не подходит
EndIf

Как можно заметить, если все нормально, то строка более-менее похожая на комплексное число приобретает вид
Код:
a[.b] + c[.d]i
Только у меня случился затык, когда я начал тестить на строках типа 5.11.11 - то есть множественные разделители целой и дробной части, и 5.11 1, когда есть пробел между цифрами которые сливаются после удаления всех пробелов - они проходят проверку.
Подскажите, как же все такие реализовать подобный финт?
Спасибо
PS: регэкспами занялся только сегодня, поэтому приму любой совет по оптимизации
 

SyDr

Сидра
Сообщения
651
Репутация
158
Re: [Регулярные выражения] Обобщенная идентификация комплексного числа

Код:
$Sp = "\d+\.?\d*\s*\+\s*\d+\.?\d*[*_x]?i"
$s = "12.356+345i"
MsgBox(4096, "", StringRegExp($s, $sp))


Пока гуру не пришли :smile:
Под данный шаблон подойдёт: число (Не записано в виде 3.1515E+32), затем любое число пробелов, затем знак +, затем любое число проюелов, затем число, затем одно из *i, _i, xi, i
 
Автор
kaster

kaster

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

Наступает на те же грабли, что и мой паттерн. Числа типа 12.1.1 + 1i проходят проверку.
Код:
$Sp = "\d+\.?\d*\s*\+\s*\d+\.?\d*[*_x]?i"
$s = "12.356.1+345i"
MsgBox(4096, "", StringRegExp($s, $sp))

Да и вообще, вот этот фрагмент, мне кажется неверным ;)
[*_x] - почти в конце.
Ты наверное забыл его экранировать

Число пробелов не важно, т.к. прежде чем скормить строку регвыру я его сначала почищу от них. Только опять же, в этом случае числа типа 1.1 1 + 12i тоже пройдут проверку
 

SyDr

Сидра
Сообщения
651
Репутация
158
Re: [Регулярные выражения] Обобщенная идентификация комплексного числа

Kaster сказал(а):
Ты наверное забыл его экранировать
Всмысле? Ты же написал, что *, - и x могут быть перед i в выражении.

Добавь в паттерн в начало \A (только в начале строки). Ждём специалистов по рег. выражениям. Я себе не представляю, как отличить "некоторый текст 123.123.123 + 123i" от "123.123.123 + 123i" и "123 + 123i"
 
Автор
kaster

kaster

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

SyDr сказал(а):
* - в регвырах это символ указывающий на то, что символ/группа/класс ему предшествующий может повторяться 0 или более раз, если нужно в строке искать именно сам символ "звездочки", то надо его экранировать - \* - вот так.
SyDr сказал(а):
Я себе не представляю, как отличить
вот вот, пока я тоже ломаю над этим голову. вернее ломал, пока сидел на работе :rofl:
а дома надо отдыхать :beer:
 

SyDr

Сидра
Сообщения
651
Репутация
158
Re: [Регулярные выражения] Обобщенная идентификация комплексного числа

Оно и так работает)) В классе у * просто не может быть другого значения.


Кстати, а зачем это нужно?




Kaster сказал(а):
пока сидел на работе
<_<
 
Автор
kaster

kaster

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

SyDr сказал(а):
Кстати, а зачем это нужно?
Делаю набор функций для работы с комплексными числами.
Матрицы+Комплексные числа+AutoIt = Готовый пакет для численного моделирования гидродинамических процессов с наиболее удобной и быстрой разработкой графического интерфейса.
Хочу сделать, примитивный гидродинамический симулятор ;)


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

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


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

никто не знает? :-\
 

amel27

Продвинутый
Сообщения
146
Репутация
55
Re: [Регулярные выражения] Обобщенная идентификация комплексного числа

Kaster сказал(а):
является ли строка условным комплексным числом.
гм... давненько я слушал курс ТФКП... не припоминаю там никаких "условностей" :-\
просто интересно, чем отличается "условное комплексное" от обычного?

Kaster сказал(а):
алгебраическая запись которых может быть представлена в виде
"a - b + ci + di" - тоже комплексное число, или требуется именно приведенный к каноническому вид?

Kaster сказал(а):
i - это мнимая единица (всегда обозначается как i)
это шутка?.. :laugh: а как же поледующие примеры с "j"?..
И что это за разделитель "_"?.. Про него нигде не сказано... :blink:

Kaster сказал(а):
Например
5[,.]1 + 2[,.]1[*_x][ij] - да
5[,.] + 2[,.][*_x][ij] - да
5 + 2[*_x][ij] - да
5 + 2[ij] - да
[a-z] + ... - нет
... + [a-z]... - нет
ИМХО все же лучше было привести примеры чисел, а не паттернов.. ;)
 
Автор
kaster

kaster

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

Привет, amel27
не припоминаю там никаких "условностей
в тфкп нет никаких условностей. но мы ведь говорим про Autoit, не так ли? а там нет такого типа как комплексное число
чем отличается "условное комплексное" от обычного?
я буду сравнивать комп. число не с обычным, а со строками, а отличие будет как раз в наличии отличительных черт выраженных через паттер
или требуется именно приведенный к каноническому виду
да, вид должен быть "обобщенно" канонический 8) про обобщенность ниже
это шутка?.. :laugh: а как же поледующие примеры с "j"?..
имелось в виду, что в тфкп мнимая единица это "i"
но ничто не мешает ввести и j, причем с разделителем (разными) и без
Про него нигде не сказано
в списке с "да" и "нет" этот разделитель указан ;) - [*_x]
а принцип распознавания следующий
1. любое кол-во пробелов в строке (они отсекутся до сравнения с паттерном)
2. после удаления пробелов, строка должна начинаться с числа, которое может быть как целым, так и дробным. разделителем целой и дробной части может быть как точка так и запятая
3. после числа идет знак "+" или "-" (про минус кстати забыл указать вначале ;D)
4. за ним опять число, опять может быть дробным или целым, разделитель точка или запятая
5. потом может быть а может и не быть разделителя. разделителем может быть либо "*", либо "_", либо "х"
6. потом либо "i" либо "j"
7. если строка удовлетворяет такому паттерну, она признается как комп. число а затем все запятые в качестве разделителя целой и дробной части преобразуются в точки, все разделители числа и мнимой единицы удаляются

примерно так :smile:
тот паттерн что указал я, подходит практически под все нужные строки. НО!!!
числа типа "1.1.1 + 2j" к сожалению тоже удовлетворяют ему... а хотелось бы чтобы нет...
уф...
есть иде? :-[
 

amel27

Продвинутый
Сообщения
146
Репутация
55
Re: [Регулярные выражения] Обобщенная идентификация комплексного числа

Kaster сказал(а):
Даров, Kaster
:beer:

Kaster сказал(а):
в тфкп нет никаких условностей. но мы ведь говорим про Autoit, не так ли? а там нет такого типа как комплексное число
понял, но тогда речь о представлении числа, а не о самом числе... ;)

Kaster сказал(а):
а принцип распознавания следующий
1. отсекутся до сравнения?... а как же быть "5.11 1"?
2. действительная часть не может быть отрицательной?.. а нулевой, т.е. отсутствовать совсем?
4. комплексная часть всегда ненулевая?.. т.е. обязательно присутствует?
5. регистр важен?.. "X" допустимо?
6. регистр не важен?.. "I" либо "J" допустимы?

Kaster сказал(а):
я ваще нудный... =)

Kaster сказал(а):
кане ;)



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

как рабочий вариант:
Код:
$sString = " 1.1.1 + 2j "

$sRegExp = "^\s*((\d+)?\.)?\d+\s*[+-]\s*((\d+)?\.)?\d+\s*[*_x]?\s*[ij]\s*$"
ConsoleWrite( (StringRegExp($sString, $sRegExp)=1) &@CRLF)
 
Автор
kaster

kaster

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

1. отсекутся до сравнения?... а как же быть "5.11 1"?
да. это тоже было частью проблемы. а отсекал я их чтобы было легче паттерн строить, т.к. пока опыта мало. поэтому в идеале, такие числа не должны проходить ;D
действительная часть не может быть отрицательной?.. а нулевой, т.е. отсутствовать совсем
конечно может. это я недоглядел. но если ее нет совсем, то надо ставить хотя бы 0, иначе совсем будет путаница (как мне кажется)
то есть в принципе могут быть числа типа -1 + 2i, 0 + 2i, 5 - 0i
комплексная часть всегда ненулевая?.. т.е. обязательно присутствует?
скажем так - не всегда ненулевая, но присутствовать должна всегда. см. пример выше
о. еще один момент. не важен.
как рабочий вариант:
спасибо, буду тестить. о результатах отпишусь



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

amel27
кстати, в AutoIt работает ^ и $ - как начало и конец строки? просто в доках этого нет. там вроде как \A и \z
 

amel27

Продвинутый
Сообщения
146
Репутация
55
Re: [Регулярные выражения] Обобщенная идентификация комплексного числа

Kaster сказал(а):
кстати, в AutoIt работает ^ и $ - как начало и конец строки? просто в доках этого нет. там вроде как \A и \z
угу, смысл аналогичен - без модификатора (?m) метасимволы ^ и $ обозначают начало/конец всего текста, с ним - начало/конец строки (ограниченных CRLF) - об этом в справке, как ни странно, сказано...
:smile:
по теме топика... мне больше нравится следующий подход:

Код:
$sString = "- 1.11 + 2j +3- 5 * j"
$sRegExp = "(?i)^((^|\s*[+-])\s*((\d+)?\.)?\d+(\s*[*_x]?\s*[ij]\s*)?)+$"

ConsoleWrite( (StringRegExp($sString, $sRegExp)=1) &@CRLF)



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

З.Ы. блин, забыл про запятую... но думаю сам добавишь :smile:
 
Автор
kaster

kaster

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

amel27 сказал(а):
б этом в справке, как ни странно, сказано...
:-[
amel27 сказал(а):
по теме топика... мне больше нравится следующий подход:
не, там число не в каноническом виде. мне для дальнейших операций это очень неудобно, приводить число к каноническому виду. и так выбор достаточно широк, и точки, и запятые, и разделители, и без, и разные мнимые единицы. вобщем, пока что первый регвыр вполне себе прилично справляется. так что большое спасибище... единственное, он в качестве разделителя мнимой части и мнимой единицы помимо указанных символов принимает еще и пробелы, по всей видимости ;D
то есть вот такой фрагмент выдает True
Код:
$sString = " 1.1 + 2  x     j "

$sRegExp = "^\s*((\d+)?\.)?\d+\s*[+-]\s*((\d+)?\.)?\d+\s*[*_x]?\s*[ij]\s*$"
ConsoleWrite( (StringRegExp($sString, $sRegExp)=1) &@CRLF)

буду дальше разбираться ;)


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

аа. нашел, вот они лишние пробелы
$sRegExp = "^\s*((\d+)?\.)?\d+\s*[+-]\s*((\d+)?\.)?\d+\s*[*_x]?\s*[ij]\s*$"
 

amel27

Продвинутый
Сообщения
146
Репутация
55
Re: [Регулярные выражения] Обобщенная идентификация комплексного числа

Kaster сказал(а):
аа. нашел, вот они лишние пробелы

гм.. почему лишние?.. я почему-то решил, что пробелы тоже допустимы :whistle:
 
Автор
kaster

kaster

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

amel27 сказал(а):
гм.. почему лишние?.. я почему-то решил, что пробелы тоже допустимы :whistle:
ну, можно конечно и оставить. вообще рай для того кто вводит, никаких ограничений :D


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

Вот еще.
amel27
Подскажи пож-та, я тут уже успел понять, что определенные куски текста удовлетворившие куску паттерна в скобке можно использовать в виде \n - где n - номер группы. мне интересно, а как нумеруются группы? а если они вложены?


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

Вот последний вариант, пойдет в UDF
Код:
Global Const $sPattern = '(?i)^\s*[+-]?((\d+)?[.,])?(\d*)?\s*[+-]\s*((\d+)?[.,])?(\d+)?[*_x]?[ij]\s*$'
 

algowa

Новичок
Сообщения
1
Репутация
0
А почему не сделать проще?
Вводимое выражение разделить и закатать в массив. Разделитель - знак плюс или минус.
Далее в цикле проанализировать каждый элемент на предмет пригодности. Там же фиксятся все двойные точки и тп.
Плюс сделать просчет на наличие / отсутствие мнимой единицы...
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
OffTopic:
alarma!
Некропостер detected :ninja2:

Дружище, вот что я скажу. Все что ты сказал - не проще. Это во первых. Медленнее. Это во вторых. Мне продолжать? ;)
 
Верх