【问题标题】:Test if a string is regex测试字符串是否为正则表达式
【发布时间】:2012-06-02 10:43:50
【问题描述】:

在 PHP 中,有没有一种测试字符串是正则表达式还是普通字符串的好方法?

理想情况下,我想编写一个函数来运行一个字符串,它返回真或假。

我看了preg_last_error():

<?php
preg_match('/[a-z]/', 'test');
var_dump(preg_last_error());
preg_match('invalid regex', 'test');
var_dump(preg_last_error());
?>

显然第一个不是错误,而第二个是。但是preg_last_error() 两次都返回int 0

有什么想法吗?

【问题讨论】:

  • 也许您可以使用正则表达式进行测试^^
  • 'invalid regex' 是一个 valid 正则表达式 - 事实上,任何不涉及正则表达式特殊字符的字符串都是有效的正则表达式。请改用'['
  • 致那些关心的人:'[' 不是有效的正则表达式,因此并非所有字符串都是有效的正则表达式。
  • @AasmundEldhuset, 'invalid regex' 实际上不是一个有效的正则表达式,PHP 返回Warning: preg_match() [function.preg-match]: Delimiter must not be alphanumeric or backslash in D:\xampp\htdocs\overheard\test.php on line 5
  • @ThiefMaster:除非这会使有效的正则表达式无效。

标签: php regex preg-match


【解决方案1】:

测试字符串是否为正则表达式的最简单方法是:

if( preg_match("/^\/.+\/[a-z]*$/i",$regex))

这将告诉您字符串是否很有可能被用作正则表达式。但是,有许多字符串可以通过该检查,但无法成为正则表达式。中间未转义的斜线、末尾的未知修饰符、不匹配的括号等都可能导致问题。

preg_last_error 返回 0 的原因是因为“无效的正则表达式”不是:

  • PREG_INTERNAL_ERROR(内部错误)
  • PREG_BACKTRACK_LIMIT_ERROR(过度强制回溯)
  • PREG_RECURSION_LIMIT_ERROR(过度递归)
  • PREG_BAD_UTF8_ERROR(UTF-8 格式错误)
  • PREG_BAD_UTF8_OFFSET_ERROR(偏移到 UTF-8 字符的中间)

【讨论】:

  • 是的,这是正确的!有这种想通,只是不知道如何正确地去做!但是,使用 track_errors 有效!
  • 另请注意,这仅适用于带有/ 分隔符的正则表达式。
【解决方案2】:

这是一个很好的答案:

https://stackoverflow.com/a/12941133/2519073

if(@preg_match($yourPattern, null) === false){
    //pattern is broken
}else{
    //pattern is real
}

【讨论】:

  • 其余 2 个更好的解决方案,因为 PHP 7.2 已弃用 track_errors
【解决方案3】:

在 PHP 中测试正则表达式是否有效的唯一简单方法是使用它并检查是否引发了警告。

ini_set('track_errors', 'on');
$php_errormsg = '';
@preg_match('/[blah/', '');
if($php_errormsg) echo 'regex is invalid';

但是,使用任意用户输入作为正则表达式是一个坏主意。之前在 PCRE 引擎中存在安全漏洞(缓冲区溢出 => 远程代码执行),可能会创建需要大量 cpu/内存来编译/执行的特制长正则表达式。

【讨论】:

  • 这不是任意的用户输入,而是从数据库表中获取的行,只能通过直接代码添加(用于链接生成)。但是,是的,这有效:) 谢谢!
  • 为什么这比只检查 preg_match 的输出更好?
  • track_errors 自 PHP 7.2 起已弃用
【解决方案4】:

为什么不直接使用...另一个正则表达式?三行,没有@ kludges 或任何东西:

// Test this string
$str = "/^[A-Za-z ]+$/";

// Compare it to a regex pattern that simulates any regex
$regex = "/^\/[\s\S]+\/$/";

// Will it blend?
echo (preg_match($regex, $str) ? "TRUE" : "FALSE");

或者,以函数形式,更漂亮:

public static function isRegex($str0) {
    $regex = "/^\/[\s\S]+\/$/";
    return preg_match($regex, $str0);
}

这不测试有效性;但看起来问题是Is there a good way of test if a string is a regex or normal string in PHP?,它确实做到了。

【讨论】:

  • 我认为这是因为您无法使用正则表达式检测所有正则表达式 - 最好的办法是确定它是否看起来有点像正则表达式。
  • 对于正则表达式爱好者来说,this question 的答案可能很有趣...
  • 不适用于标志?示例 '/(\n)}[\s\n\r]*$/s'
  • 这个答案不支持修饰符
猜你喜欢
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
相关资源
最近更新 更多