Validate sprintf format from input field with regex

后端 未结 3 1773
说谎
说谎 2021-01-21 00:15

I have an input field where both regular text and sprintf tags can be entered.

Example: some text here. %1$s done %2$d times

How do I validate the s

相关标签:
3条回答
  • 2021-01-21 00:41

    The UTF-8 modifier is not necessary unless you use UTF-8 in your pattern. And beside that the sprintf format is more complex, try the following

    /%(?:\d+\$)?[dfsu]/
    

    This would match both the %s and %1$s format.

    But if you want to check every occurrence of % and whether a valid sprintf() format is following, regular expressions would not be a good choice. A sequential parser would be better.

    0 讨论(0)
  • 2021-01-21 00:44

    This is what I ended up with, and its working.

    // Always use server validation even if you have JS validation
    if (!isset($_POST['input']) || empty($_POST['input'])) {
      // Do stuff
    } else {
      $matches = explode(' ',$_POST['input']);
      $validInput = true;
    
      foreach ($matches as $m) {
        // Check if a slice contains %$[number] as it indicates a sprintf format
        if (preg_match('/[%\d\$]+/',$m) > 0) {
          // Match found. Now check if its a valid sprintf format
          if ($validInput === false || preg_match('/^%(?:\d+\$)?[dfsu]$/u',$m)===0) {   // no match found
            $validInput = false;
            break; // Invalid sprintf format found. Abort
          }
        }
      }
    
      if ($validInput === false) {
        // Do stuff when input is NOT valid
      }
    }
    

    Thank you Gumbo for the regex pattern that matches both with and without order marking.

    Edit: I realized that searching for % is wrong, since nothing will be checked if its forgotten/omitted. Above is new code.

    "$validInput === false ||" can be omitted in the last if-statement, but I included it for completeness.

    0 讨论(0)
  • 2021-01-21 00:47

    I originally used Gumbo's regex to parse sprintf directives, but I immediately ran into a problem when trying to parse something like %1.2f. I ended up going back to PHP's sprintf manual and wrote the regex according to its rules. By far I'm not a regex expert, so I'm not sure if this is the cleanest way to write it:

    /%(?:\d+\$)?[+-]?(?:[ 0]|'.{1})?-?\d*(?:\.\d+)?[bcdeEufFgGosxX]/
    
    0 讨论(0)
提交回复
热议问题