Проверьте формат sprintf из поля ввода с помощью регулярного выражения - PullRequest
3 голосов
/ 15 января 2009

У меня есть поле ввода, в которое можно вводить как обычный текст, так и теги sprintf.

Пример: some text here. %1$s done %2$d times

Как мне проверить части sprintf, чтобы они не могли ошибаться, как %$1s? Текст utf-8, и, насколько мне известно, регулярные выражения соответствуют только латинским символам 1.

www.regular-expressions.info нигде не перечисляет /u, что, как мне кажется, используется для определения того, что строка является Unicode.

Является ли лучший способ просто найти всю строку входного поля для % или $ и, если найден, применить регулярное выражение для проверки частей sprintf?

Я думаю, что регулярное выражение будет: /%\d\$(s|d|u|f)/u

Ответы [ 3 ]

6 голосов
/ 18 января 2012

Изначально я использовал регулярное выражение Gumbo для разбора директив sprintf, но сразу столкнулся с проблемой при попытке проанализировать что-то вроде% 1.2f. В итоге я вернулся к руководству PHP по sprintf и написал регулярное выражение в соответствии с его правилами. На данный момент я не эксперт по регулярным выражениям, поэтому я не уверен, что это самый чистый способ написать это:

/%(?:\d+\$)?[+-]?(?:[ 0]|'.{1})?-?\d*(?:\.\d+)?[bcdeEufFgGosxX]/
2 голосов
/ 15 января 2009

Модификатор UTF-8 не требуется, если вы не используете UTF-8 в своем шаблоне. Кроме того, формат sprintf более сложный, попробуйте следующее

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

Это будет соответствовать форматам %s и %1$s.

Но если вы хотите проверить каждое вхождение % и следит ли правильный формат sprintf(), регулярные выражения не будут хорошим выбором. Последовательный парсер будет лучше.

0 голосов
/ 15 января 2009

Это то, чем я закончил, и это работает.

// 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
  }
}

Спасибо, Gumbo, за шаблон регулярного выражения, который соответствует как с маркировкой заказа, так и без нее.

Редактировать : Я понял, что поиск% неправильный, так как ничего не будет проверено, если он забыт / опущен. Выше новый код.

"$ validInput === false ||" может быть опущено в последнем операторе if, но я включил его для полноты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...