Что нового

Как задать формат строке ввода с помощью регулярных выражений (в input напр.)?

hellm

Новичок
Сообщения
32
Репутация
1
Такой формат строки необходим(формат цены): 4 цифры или ноль, если первая запятая - точка заменяемая на запятую или запятая - 2 цифры, если одна или не одной добавить нули.
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Лучше покажите список возможных форматов. А то не очень понятно.
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
вот формат на выходе ####,##

набрано может быть не более 4х цифр перед запятой (####,##) -> если на входе первой идет запятая, на выходе 0,##

точка заменяемая на запятую или запятая -> на входе ####.## на выходе ####,## если запятая уже есть, тогда ничего не менять

набрано может быть не более 2х цифр после запятой (####,##) -> если на входе одна или не одной добавить нули -> #,# или #, или # на выходе #,#0 или #,00 (для посл. случаев)

все форматы не смогу просчитать, наверное... :(
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Так?
Код:
$str = '08800,8439'
$arr = StringRegExp($str, '^.*?0*([^.,]{0,4})[.,]?(\d*).*$', 3)
$str = StringFormat('%.2f', Number($arr[0]&'.'&$arr[1],3))
$str = StringReplace($str, '.', ',')
ConsoleWrite($str)
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
То что доктор прописал! Поясните, пожалуйста, как расшифровывается регулярное выражение?

А можно еще туда кое-что добавить?
Вот, например, если ввести k,5 программа пишет 0,00 вместо 0,50 или, скажем если набарть два раза запятую ,,5 или .,5 или ..5 программа выдает 0,00 вместо 0,50, если набирать буквы с цифрой s3 - получем на выходе 0,00 вместо 3,00
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
hellm
Вариант ограничения ввода при помощи интерфейса
Код:
#include <EditConstants.au3>

GUICreate("", 150, 30)
$inp1 = GUICtrlCreateInput("", 5, 5, 30, -1, BitOR($ES_NUMBER, $ES_RIGHT))
$lbl  = GUICtrlCreateLabel(",", 35, 5, 5)
        GUICtrlSetFont(-1, 14, 700)
$inp2 = GUICtrlCreateInput("", 40, 5, 20, -1, $ES_NUMBER)
$btn  = GUICtrlCreateButton("Результат", 65, 5, 70, 20)

GUISetState()

Do
  Switch GUIGetMsg()
    Case -3
      Exit
    Case $btn
      MsgBox(0, "", CheckResult())
  EndSwitch
Until 0

Func CheckResult()
  Local $1 = GUICtrlRead($inp1)
  Local $2 = GUICtrlRead($inp2)
  If $1 = "" Then
    $1 = "0"
  Else
    $1 = Int($1)
  EndIf
  If $2 = "" Then
    $2 = "00"
  ElseIf StringLen($2) = 1 Then
    $2 &= "0"
  EndIf
  Return $1 & "," & $2
EndFunc
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
Это суперское решение! Мне нравится.

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

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
hellm [?]
Запятая хоть есть на numpad'e
Не знаю, что у вас за numpad... у меня только точка.
Но разве нам кто-то запрещает использовать эту точку в качестве TAB ?
Код:
; в начале скрипта
HotKeySet("{NUMPADDOT}", "SendTab")
...
; в конце скрипта
Func SendTab()
  Send("{TAB}")
EndFunc

И набирайте цену с цифровой клавиатуры.
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
hellm
Код:
$str = '08800,8439'
$arr = StringRegExp($str, '^0*(\d{0,4})[.,]?(\d*).*$', 3)
$str = StringFormat('%.2f', Number($arr[0]&'.'&$arr[1],3))
$str = StringReplace($str, '.', ',')
ConsoleWrite($str)
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
Z_Lenar

Поясните, пожалуйста, код регулярного выражения.
 

ivsatel

Продвинутый
Сообщения
319
Репутация
84
hellm
hellm сказал(а):
Вот, например, если ввести k,5 программа пишет 0,00 вместо 0,50 или, скажем если набарть два раза запятую ,,5 или .,5 или ..5 программа выдает 0,00 вместо 0,50, если набирать буквы с цифрой s3 - получем на выходе 0,00 вместо 3,00

Тогда так:
Код:
$str = ',.,5'
$str = StringRegExpReplace($str, '^\D+?(\,\d+|\d+)', '0$1')
$arr = StringRegExp($str, '^0*(\d{0,4})[.,]?(\d*).*$', 3)
$str = StringFormat('%.2f', Number($arr[0]&'.'&$arr[1],3))
$str = StringReplace($str, '.', ',')
ConsoleWrite($str)
 
Автор
H

hellm

Новичок
Сообщения
32
Репутация
1
ivsatel

А как запись регулярного выражения расшифровать? (я не повторяюсь, я не повторяюсь) ;)
 

ivsatel

Продвинутый
Сообщения
319
Репутация
84
hellm
hellm сказал(а):

Код:
^0*(\d{0,4})[.,]?(\d*).*$
Начало строки с нуля, захватить от нуля до 4-х цифр, после точка или запятая, до следующих цифр, далее что угодно, до конца строки.
Примерно так)
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
hellm
Извините, не учел заканчивающих букв.
Вот исправление:
Код:
^(?:0*(\d{0,4})[.,]?(\d*)|(.*))$
^ - Начало строки
(?:...) - Негруппируемый класс
$ - Конец строки (т.е. все что внутри предыдущего класса должно захватить "всю строку".
0* - Символ '0' повторяется 0 и более раз
(\d{0,4}) -
\d{0,4} - Цифры повторяются от 0 до 4-х раз
(\d{0,4}) - Захватываем цифры или '' (ничего) в группу с номером 1 (была бы 2, если бы не '?:' в начале "данной группировки")
[.,]? - Возможен символ точки или запятой
(\d*) - Захватываем 0 или более цифр во 2 группу
| - Или. Т.е. если строка не соответствовала шаблону "начало_строки-возможные_4_цифры-возможная_точка_или_запятая-возможные_цифры-конец_строки" пытаемся применить следующий шаблон:
(.*) - Захватываем "все" в 3 группу.

Если передать "0," - 1-группа: 0, 2-ая: '' (пусто)
Если передать "." - 1-группа: '', 2-ая: ''
Если передать '123456' - 1-группа: 1234 (не более 4-х цифр), 2-ая: 56 (содержит остатки после первой группы)
Если передать 123a.23 - 1-группа: '', 2-ая: '', 3-я: '123a.23' (т.е. первый шаблон не сработал - все символы отдали 3-ей группе)
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
ivsatel
Я хотел бы немного поправить Ваш код:
Код:
$str = ',.,5'
$str = StringRegExpReplace($str, '^\D*?(\,\d+|\d+)', '0$1')
$arr = StringRegExp($str, '^0*(\d{0,4})[.,]?(\d*).*$', 3)
$str = StringFormat('%.2f', Number($arr[0]&'.'&$arr[1],3))
$str = StringReplace($str, '.', ',')
ConsoleWrite($str)


В частности именно этот кусок:
Код:
'^\D*?'


В этом случае, если мы укажем значение начиная с запятой, а не с символа, то 0 все равно добавится в начало. В противном случае получится менее привлекательное число
 

mef-t

Осваивающий
Сообщения
306
Репутация
30
А Вам как надо, чтобы начиналось с точки или с нуля?
Я предположил, что раз речь идет о цене, то правильнее, чтобы начиналось с 0.
Потому и подкорректировал.

Для примера, введите исходное значение равное ",53".
Проверьте что будет в одном и другом случае.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
mef-t
Не обратил внимания что вы привели поправленный вариант. Ваш однозначно лучше.
 
Верх