Регулярное выражение для определения наличия в строке заполнителей printf - PullRequest
2 голосов
/ 02 августа 2011

Я ищу регулярное выражение, которое будет правильно определять наличие в строке заполнителей вида printf ().

Ответы [ 2 ]

5 голосов
/ 02 апреля 2015

Оказывается, это немного сложнее, чем кажется, и ответ будет зависеть от того, что вы хотите сделать с заполнителями, и какой язык / спецификацию вы используете как для printf, так и для регулярных выражений.

Чтобы дать вам пример того, как это выглядит на практике, вот регулярное выражение-заполнитель из библиотеки sprintf.js, которое соответствует ее собственной спецификации заполнителя , которая похожа, но не идентична c ++ spec , который похож, но не идентичен php spec :

placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fiosuxX])/,

Вы можете получить отличное объяснение всех битов и кусочков, используя что-то вроде regex101 https://regex101.com/r/bV9nT8/1 но есть две ключевые вещи, которые следует учитывать в широком смысле:

1) '^' в начале: в реализации Regexp на языке javascript отсутствует \ G "Конец предыдущего соответствия"якорь, который делает невозможным сопоставление смежных заполнителей ('%s%s' => ['%s','%s']), игнорируя экранированные знаки '%' ('%s%%s' => ['%s']). В результате эта прога библиотекиrammatics обрабатывает простой текст и %% подстроки перед попыткой регулярного выражения заполнителя.

2) Группы захвата: как часть библиотеки синтаксического анализа, это регулярное выражение захватывает много вещей, которые ему нужно знать:

  1. цифры в $1s (индекс аргумента)
  2. имя в $(variableName)s
  3. + после скобок, если оно присутствует
  4. Либо 0, либо ', за которым следует другая последовательность символов (я думаю, что это символ заполнения)
  5. необязательный - символ
  6. Дополнительные цифры (минимальная ширина поля)
  7. Больше цифр (точность с плавающей запятой)
  8. спецификатор типа

В зависимости от вашей цели вы, вероятно, захотите подмножество этих вещей, или, возможно, ни одну из них, столько одна группа захвата для всего выражения, например:

var regexForPlaceholders = /(?:\x25\x25)|(\x25(?:(?:[1-9]\d*)\$|\((?:[^\)]+)\))?(?:\+)?(?:0|'[^$])?(?:-)?(?:\d+)?(?:\.(?:\d+))?(?:[b-fiosuxX]))/g;
function placeholders(string ){
return ( string.match( regexForPlaceholders ) || [] )
        .filter( function( v ) {
            return v !== '\x25\x25';
        } );
}
2 голосов
/ 02 августа 2011

Рассмотрим регулярное выражение -

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

Вы также должны взглянуть на этот предыдущий ответ - Проверить формат sprintf из поля ввода с помощью регулярного выражения

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