0

I need to check a string that comes from an ajax post with php, in particulare the source is a text area with this format:

[minute]:[price]
[minute]:[price]
[minute]:[price]

Example:

10:20
12:22.23
20:30.1

And so on, the minutes is an integer and the price could be a float with 0 to 2 decimals(10, 10.0, 10.00 are fine), I'm only able to check them in a simple way: double explode( "\n" and ":") and is_number + float on sub-element, but it looks pretty inconvenient, could someone suggests me an expression to use with preg_match?

9
  • 5
    Put your attempt first? Commented Dec 25, 2013 at 19:03
  • Now that is a good expression looks pretty inconvenient, Why not try something fist and ask us why it is not working? Commented Dec 25, 2013 at 19:07
  • Ehm...it's a shame, but I don't know almost nothing about regex :( Commented Dec 25, 2013 at 19:10
  • This worked for me: (\d)+:(\d)+(.(\d)+)* - Check out this website for testing your regex: debuggex.com/#cheatsheet - I have only just started learning regex so there might be a better one but it worked for your 3 examples. Commented Dec 25, 2013 at 19:11
  • @Jessica the string comes from a textarea and I don't know if the new line could influence the regex Commented Dec 25, 2013 at 19:14

4 Answers 4

1

This is probably what you want:

$re = '/[\d]{1,2}\:[\d]{1,2}(?:\.[\d]{1,2})?/m';
$str = "12:22\n12:22.23\n12:22.23";

preg_match_all($re, $str, $matches); //This catch only correct values

echo "<pre>";
foreach($matches[0] as $value){
  $split = explode(":", $value);
  $minute = intval($split[0]);
  $price = floatval($split[1]);

  echo "minute -> " . $minute . " value -> " . $price . "\n";
}

The expression /[\d]{1,2}\:[\d]{1,2}(?:\.[\d]{1,2})?/m catch patterns like 12:12.12. See Regex101 example

preg_match_all($pattern, $subject, $matches) Perform a global regular expression match and put the matches into the $matches array.

intval($split[0]);floatval(split[1]); will ensure that the values are in the correct format.

Sign up to request clarification or add additional context in comments.

2 Comments

Why do you put \d in character class?
M42 did it to refer to any digit caracter. Instead of [\d] could be also [0-9]
1
preg_match(/\d{1,}:\d{1,}([.][0-9]{1,})?/s);

3 Comments

/\d{1,}:\d{1,}(?:\.\d{0,2})?/s better
it validates also: 12:22.23xxxxx
This doesn't match 25:12 (price without decimal)
0
^\d+:\d+(\.\d{1,2})?$

In:

if(preg_match("/^\d+:\d+(\.\d{1,2})?$/", $str))
{
    echo "Valid input!";
}

Live demo

Comments

0

After reading your answers:

/^(\d){1,}?\:(\d){1,}(?:\.(\d){1,2})?$/mi

and this the complete function:

preg_match_all(' /^(\d){1,}?\:(\d){1,}(?:\.(\d){1,2})?$/mi', $_POST['ratetable'], $out);
if($out[0]!=explode("\n",$_POST['ratetable'])){
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(array(0=>'Invalid price table at line: '.implode(", ", array_diff_key(array_flip(explode("\n",$_POST['ratetable'])),array_flip($out[0])))));
    exit();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.