正则表达式检测字符串是否包含printf占位符

时间:2011-08-02 16:04:39

标签: regex printf

我正在寻找一个正则表达式,它可以正确检测字符串中是否有printf()种占位符。

2 个答案:

答案 0 :(得分:5)

事实证明这比它看起来有点棘手,答案取决于你想要对占位符做什么,以及你对printf和正则表达式使用的语言/规范。

为了举例说明它在实践中的样子,这里是来自sprintf.js库的占位符正则表达式,它匹配它自己的placeholder spec,这是相似但不是与c++ spec相同但与php spec相似但不完全相同:

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

你可以使用像regex101 https://regex101.com/r/bV9nT8/1之类的东西来获得对所有位和peices的一个很好的解释,但有两个关键的事情需要考虑,它们将具有广泛的相关性:

1)' ^'一开始:javascript Regexp实现缺少\ G"上一场比赛的结束"锚点,这使得无法匹配相邻的占位符('%s%s' => ['%s','%s']),同时忽略转义的'%'标记('%s%%s' => ['%s'])。因此,此库在编写占位符正则表达式之前以编程方式处理纯文本和%%子字符串。

2)捕获组:作为解析库的一部分,这个正则表达式捕获了许多需要知道的事情:

  1. $1s(参数索引)
  2. 中的数字
  3. $(variableName)s
  4. 中的名称
  5. 括号后的+(如果它存在)
  6. 0或'后跟另一个字符序列(我认为这是填充字符)
  7. 可选的-字符
  8. 更多数字(最小字段宽度)
  9. 更多数字(浮点精度)
  10. 类型说明符
  11. 根据您的目的,您可能需要这些内容的子集,或者可能不需要这些内容的子集,整个表达式只有一个捕获组,例如:

    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';
            } );
    }
    

答案 1 :(得分:2)

考虑正则表达式 -

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

你也应该看看这个先前的答案 - Validate sprintf format from input field with regex