Автор Тема: [RegExp] Обобщенная идентификация комплексного числа  (Прочитано 9346 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020
  • Репутация: 622
  • Пол: Мужской
  • Мой Аватар, он лучший самый
    • Награды
  • Версия AutoIt: 3.3.14.0
Гуру регэкспов (не будем тыкать пальцАми)  :)
Подскажите, как можно посредством регулярных выражений распознать является ли строка условным комплексным числом.
Поясняю:
Комплексное число - это пара действительных чисел, алгебраическая запись которых может быть представлена в виде
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]... - нет
присутствие любых символов кроме цифр, точки/запятой (как разделитель целой и дробной части), знаков *, _, х (разделитель мнимой части от мнимой единицы) - нет
Для этих целей я соорудил следующую конструкцию
Код: AutoIt [Выделить]
$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: регэкспами занялся только сегодня, поэтому приму любой совет по оптимизации
« Последнее редактирование: Октябрь 17, 2009, 22:37:36 от Kaster »
Конференция посвященная AutoIt на jabber.ru - [email protected]
Как попасть на конференцию читаем тут


Русское сообщество AutoIt

[RegExp] Обобщенная идентификация комплексного числа
« Отправлен: Октябрь 16, 2009, 19:17:40 »

Оффлайн SyDr [?]

  • Локальный модератор
  • *
  • Сообщений: 649
  • Репутация: 157
  • Пол: Мужской
  • Сидра
    • Награды
  • Версия AutoIt: 3.3.12.0
Код: AutoIt [Выделить]
$Sp = "\d+\.?\d*\s*\+\s*\d+\.?\d*[*_x]?i"
$s = "12.356+345i"
MsgBox(4096, "", StringRegExp($s, $sp))


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


Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020

  • Автор темы
  • Репутация: 622
  • Пол: Мужской
  • Мой Аватар, он лучший самый
    • Награды
  • Версия AutoIt: 3.3.14.0
Наступает на те же грабли, что и мой паттерн. Числа типа 12.1.1 + 1i проходят проверку.
Код: AutoIt [Выделить]
$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 [?]

  • Локальный модератор
  • *
  • Сообщений: 649
  • Репутация: 157
  • Пол: Мужской
  • Сидра
    • Награды
  • Версия AutoIt: 3.3.12.0
Ты наверное забыл его экранировать
Всмысле? Ты же написал, что *, - и x могут быть перед i в выражении.

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

Русское сообщество AutoIt


Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020

  • Автор темы
  • Репутация: 622
  • Пол: Мужской
  • Мой Аватар, он лучший самый
    • Награды
  • Версия AutoIt: 3.3.14.0
Всмысле?
* - в регвырах это символ указывающий на то, что символ/группа/класс ему предшествующий может повторяться 0 или более раз, если нужно в строке искать именно сам символ "звездочки", то надо его экранировать - \* - вот так.
Я себе не представляю, как отличить
вот вот, пока я тоже ломаю над этим голову. вернее ломал, пока сидел на работе  :rofl:
а дома надо отдыхать  :beer:

Оффлайн SyDr [?]

  • Локальный модератор
  • *
  • Сообщений: 649
  • Репутация: 157
  • Пол: Мужской
  • Сидра
    • Награды
  • Версия AutoIt: 3.3.12.0
Оно и так работает)) В классе у * просто не может быть другого значения.


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




пока сидел на работе
<_<

Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020

  • Автор темы
  • Репутация: 622
  • Пол: Мужской
  • Мой Аватар, он лучший самый
    • Награды
  • Версия AutoIt: 3.3.14.0
Кстати, а зачем это нужно?
Делаю набор функций для работы с комплексными числами.
Матрицы+Комплексные числа+AutoIt = Готовый пакет для численного моделирования гидродинамических процессов с наиболее удобной и быстрой разработкой графического интерфейса.
Хочу сделать, примитивный гидродинамический симулятор  ;)


Добавлено: Октябрь 16, 2009, 23:03:27
В классе у * просто не может быть другого значения.
аа. вот оно что, буду знать. я ведь по правилам пока все делаю  :D


Добавлено: Октябрь 17, 2009, 10:31:43
никто не знает?  :-\
« Последнее редактирование: Октябрь 17, 2009, 10:31:43 от Kaster, Причина: Объединение сообщений »

Оффлайн amel27 [?]

  • VIP
  • *
  • Сообщений: 146
  • Репутация: 55
  • Пол: Мужской
    • Награды
является ли строка условным комплексным числом.
гм... давненько я слушал курс ТФКП... не припоминаю там никаких "условностей"  :-\
просто интересно, чем отличается "условное комплексное" от обычного?

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

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

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

Русское сообщество AutoIt


Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020

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

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

Оффлайн amel27 [?]

  • VIP
  • *
  • Сообщений: 146
  • Репутация: 55
  • Пол: Мужской
    • Награды
Привет, amel27
Даров, Kaster
:beer:

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

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

уф...
я ваще нудный... =)

есть иде?  :-[
кане  ;)



Добавлено: Октябрь 17, 2009, 14:35:22
как рабочий вариант:
Код: AutoIt [Выделить]
$sString = " 1.1.1 + 2j "

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

« Последнее редактирование: Октябрь 17, 2009, 14:35:22 от amel27, Причина: Объединение сообщений »

Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020

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



Добавлено: Октябрь 17, 2009, 16:48:45
amel27
кстати, в AutoIt работает ^ и $ - как начало и конец строки? просто в доках этого нет. там вроде как \A и \z
« Последнее редактирование: Октябрь 17, 2009, 16:48:45 от Kaster, Причина: Объединение сообщений »

Оффлайн amel27 [?]

  • VIP
  • *
  • Сообщений: 146
  • Репутация: 55
  • Пол: Мужской
    • Награды
кстати, в AutoIt работает ^ и $ - как начало и конец строки? просто в доках этого нет. там вроде как \A и \z
угу, смысл аналогичен - без модификатора (?m) метасимволы ^ и $ обозначают начало/конец всего текста, с ним - начало/конец строки (ограниченных CRLF) - об этом в справке, как ни странно, сказано...
:)
по теме топика... мне больше нравится следующий подход:

Код: AutoIt [Выделить]
$sString = "- 1.11 + 2j +3- 5 * j"
$sRegExp = "(?i)^((^|\s*[+-])\s*((\d+)?\.)?\d+(\s*[*_x]?\s*[ij]\s*)?)+$"

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



Добавлено: Октябрь 17, 2009, 17:31:30
З.Ы. блин, забыл про запятую... но думаю сам добавишь  :)

Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020

  • Автор темы
  • Репутация: 622
  • Пол: Мужской
  • Мой Аватар, он лучший самый
    • Награды
  • Версия AutoIt: 3.3.14.0
б этом в справке, как ни странно, сказано...
:-[
по теме топика... мне больше нравится следующий подход:
не, там число не в каноническом виде. мне для дальнейших операций это очень неудобно, приводить число к каноническому виду. и так выбор достаточно широк, и точки, и запятые, и разделители, и без, и разные мнимые единицы. вобщем, пока что первый регвыр вполне себе прилично справляется. так что большое спасибище... единственное, он в качестве разделителя мнимой части и мнимой единицы помимо указанных символов принимает еще и пробелы, по всей видимости ;D
то есть вот такой фрагмент выдает True
Код: AutoIt [Выделить]
$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)
 

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


Добавлено: Октябрь 17, 2009, 17:54:52
аа. нашел, вот они лишние пробелы
$sRegExp = "^\s*((\d+)?\.)?\d+\s*[+-]\s*((\d+)?\.)?\d+\s*[*_x]?\s*[ij]\s*$"
« Последнее редактирование: Октябрь 17, 2009, 17:55:37 от Kaster »

Оффлайн amel27 [?]

  • VIP
  • *
  • Сообщений: 146
  • Репутация: 55
  • Пол: Мужской
    • Награды
аа. нашел, вот они лишние пробелы

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

Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020

  • Автор темы
  • Репутация: 622
  • Пол: Мужской
  • Мой Аватар, он лучший самый
    • Награды
  • Версия AutoIt: 3.3.14.0
гм.. почему лишние?.. я почему-то решил, что пробелы тоже допустимы  :whistle:
ну, можно конечно и оставить. вообще рай для того кто вводит, никаких ограничений  :D


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


Добавлено: Октябрь 17, 2009, 22:38:14
Вот последний вариант, пойдет в UDF
Код: AutoIt [Выделить]
Global Const $sPattern = '(?i)^\s*[+-]?((\d+)?[.,])?(\d*)?\s*[+-]\s*((\d+)?[.,])?(\d+)?[*_x]?[ij]\s*$'
 

« Последнее редактирование: Октябрь 18, 2009, 09:54:36 от Kaster, Причина: Объединение сообщений »

Русское сообщество AutoIt


 

Похожие темы

  Тема / Автор Ответов Последний ответ
5 Ответов
4281 Просмотров
Последний ответ Июль 26, 2011, 12:15:25
от Strog
24 Ответов
11571 Просмотров
Последний ответ Ноябрь 23, 2011, 16:50:46
от alexbs
6 Ответов
3555 Просмотров
Последний ответ Октябрь 21, 2011, 13:16:54
от Trans
3 Ответов
2140 Просмотров
Последний ответ Декабрь 04, 2011, 01:55:09
от Afonichev
0 Ответов
542 Просмотров
Последний ответ Июль 14, 2015, 17:34:00
от Karpyshyn Roman
5 Ответов
3445 Просмотров
Последний ответ Сентябрь 17, 2015, 14:47:21
от Rioran
3 Ответов
3840 Просмотров
Последний ответ Сентябрь 18, 2015, 15:04:04
от AZJIO
2 Ответов
2388 Просмотров
Последний ответ Июнь 09, 2016, 14:14:59
от Dk
6 Ответов
3231 Просмотров
Последний ответ Январь 07, 2017, 01:06:34
от Alofa
2 Ответов
2212 Просмотров
Последний ответ Март 16, 2017, 01:14:10
от Skif_off