2009-01-15 19 views
3

我有一个输入字段,可以输入常规文本和sprintf标签。使用正则表达式验证输入字段的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

回答

0

这是我结束了,它的工作。

// 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语句中省略,但为了完整性我将其包含在内。

+0

您应该将第一个正则表达式更改为“/%[^ \ s] * /”,因为格式也可以在字符串结尾处具有以下空格。第二个应该改为“/ ^%(?:\ d + \ $)?[dfsu] $ /”,否则“%% 1 $ s”也会被接受为有效。 – Gumbo 2009-01-15 13:00:10

2

的UTF-8修改器是没有必要的,除非你在你的模式中使用UTF-8。而旁边的sprintf format比较复杂,请尝试以下

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

这将同时匹配%s%1$s格式。

但是,如果要检查每个出现的%以及是否遵循有效的sprintf()格式,则正则表达式不是一个好选择。顺序解析器会更好。

+0

连续解析器? 我可以使用preg_match_all来查找所有%-words,但Im在第一个空格或EOL时遇到了阻止它的问题。使用上面的例子,我会得到一个包含两个条目的数组:[0] =“%1 $ s done”,[1] =“%2 $ d times”。 $ realRegEx =爆炸(“”,[0])的作品,但必须有一些正则表达式的方式。 – Kim 2009-01-15 11:43:12

+0

'/(?<!%)%(?:\ d + \ $)?[dfsu] /'将防止转义百分比,例如'%% s'被抓到。 – donatJ 2017-02-08 22:25:51

4

我最初使用Gumbo的正则表达式来分析sprintf指令,但当试图解析类似于%1.2f的东西时,我立即遇到了问题。我最终回到了PHP的sprintf手册,并根据其规则编写了正则表达式。到目前为止,我不是一个正则表达式的专家,所以我不知道这是写它最彻底的方法:我用http://www.spaweditor.com/scripts/regex/index.php来测试它

/%(?:\d+\$)?[+-]?(?:[ 0]|'.{1})?-?\d*(?:\.\d+)?[bcdeEufFgGosxX]/ 

,我几乎复制/粘贴大部分sprintf手册中使用的指令示例,并按预期进行解析。