我正在寻找一个正则表达式,它可以正确检测字符串中是否有printf()种占位符。
答案 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)捕获组:作为解析库的一部分,这个正则表达式捕获了许多需要知道的事情:
$1s
(参数索引)$(variableName)s
+
(如果它存在)'
后跟另一个字符序列(我认为这是填充字符)-
字符根据您的目的,您可能需要这些内容的子集,或者可能不需要这些内容的子集,整个表达式只有一个捕获组,例如:
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)