正则表达式作为Php输入过滤器用于Pdo DSN主机或主机+端口

时间:2015-09-24 03:14:32

标签: php regex pdo

在前面,我不喜欢正则表达式。期望允许在单个输入中设置DSN的域或域+端口选项的输入。此外,localhost也是一个选项以及子域名。

我能来的最好的是从一篇名为Domain name regular expression example

的文章中获得的

它为Java提供了这个表达式 ^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$

我们意识到它几乎可以工作,但是一段时间的部分是\\.,在Php中应该是\.

php.net manual一些PDO_MYSQL DSN示例是:

mysql:host=localhost;dbname=testdb
mysql:host=localhost;port=3307;dbname=testdb

我想要执行正则表达式的唯一部分是

localhost
localhost;port=3307

这将用于HTML表单的过滤器,作为Php应用程序的基于Php的安装的一部分(希望这有意义)。

所以这就是我想出来的:

'/^((?!-)[a-z0-9-]{1,63}(?<!-)(\.){0,1})+([a-z]{0,9})(?<!\.)((;port=){1}[0-9]{2,6}){0,1}$/i'

字符串不以连字符开头或结尾或包含空格很重要。

以下是更深入的内容https://gist.github.com/CrandellWS/bc0cbcbb1df5c4b4361a 以及整个项目https://github.com/CrandellWS/ams

的链接

此表达式可以更短还是优化,以帮助防止最终用户错误?

更重要的是,正则表达式不是我最强烈的观点,任何可以防止的问题请解释如何以及为什么。

对于我的参考,这两个网站在确定正则表达式http://www.regexr.com/http://txt2re.com/

方面非常有帮助

3 个答案:

答案 0 :(得分:2)

如果您只想检查它是否有效,(不关心匹配组):

^[^-][a-z0-9-]{0,63}[^-](\.[a-z]{0,9})*(;port=[0-9]{2,6})?$

如果你不是那么精确,你可以测试:

^[^-][a-z0-9-]*[^-](\.[a-z]+)*(;port=[0-9]+)?$

^[^-][\w-]*[^-](\.\w+)*(;port=\d+)?$

但基本上每次缩小它都会失去准确性

更新1:

  

[\w\d-]* vs [A-Za-z0-9-]{1,63}此处不会检查字符串的长度

     

? vs {0,1}相当于(只是更短)

     

\d vs [0-9]相当于(只是更短)

     

\w vs [A-Za-z0-9_]相当于(只是更短)

     

没有负面的外观(?<! ...)他们让一切变得有点复杂

缺少准确性:现在有一些条目可能无效,因为缺少长度检查,现在也允许下划线(不在之前)

更新2:

要防止字符开头的空格,只需添加此

即可
^[^\s-][\w-]*[^\s-](\.\w+)*(;port=\d+)?$
  

[^\s-] ...排除空格或连字符,允许任何其他字符(即使是点)

但要接近你的表达(没有后卫)

^\w[\w-]*\w(\.\w+)*(;port=\d+)?$

并删除下划线,但它有点长

^[a-z0-9][a-z0-9-]*[a-z0-9](\.[a-z0-9-]+)*(;port=\d+)?$

答案 1 :(得分:1)

我可以建议尝试使其更加严格:

example

它不考虑unix_socket,它不简短但很容易理解。您可以尝试使其更精确。

已更新

另请尝试example

答案 2 :(得分:-2)

让我感到惊讶的是,DSN中的参数可以按随机顺序排列。

  

这将用于HTML表单的过滤器,作为Php应用程序的基于Php的安装的一部分

对于我的生活,我不明白为什么你会折磨用户要求他们创建类似DSN的字符串(他们可能根本不知道),然后折磨自己验证它。就像世界上任何安装脚本一样,而不仅仅是要求单独的主机和(可选)端口字段。

在开始使用之前,我建议您熟悉一些现有的安装脚本。一个来自Wordpress就可以了。

我刚刚发现,您可能需要有关PHP条件的帮助。你走了:

if (isset($_POST['dbhost'])) {

    if ($_POST['dbport'])
    {
        $DB_PORT = $_POST['dbport']
    } else {
        $DB_PORT = 3306;
    }
    $DB_HOST = $_POST['dbhost'];
    $DB_DATABASE = $_POST['dbname'];
    $DB_USERNAME = $_POST['dbuser'];
    $DB_PASSWORD = $_POST['dbpass'];
    $DB_DSN = 'mysql:host=$DB_HOST;port=$DB_PORT;dbname=$DB_DATABASE";

这个简单的代码可以解决您所有的问题,而无需您不喜欢的正则表达式。我希望你的不喜欢不会扩展到简单的条件。