【问题标题】:Java regex doesn't matchJava 正则表达式不匹配
【发布时间】:2020-04-06 16:50:35
【问题描述】:

我有这个正则表达式:

#(?<=[^\w`"\[?:]|^)[a-z_][a-z0-9_]*(?=[^\w`"(\]]|$)#Di

我正在尝试使 SQL 语法更漂亮。例如来自“SELECT * FROM users WHERE username=?;”到

SELECT * FROM `users` WHERE `username`=?;

这个正则表达式匹配所有不包含反引号的单词。在匹配组中,我正在检查是否匹配单词大写。如果是真的,那么这个词就被跳过了。其他单词被添加到反引号中。我的问题是,那个正则表达式什么都不匹配。我在 PHP 中有类似的代码,它在那里工作。

function tryDelimite(string $s): string {
    return preg_replace_callback('#(?<=[^\w`"\[?:]|^)[a-z_][a-z0-9_]*(?=[^\w`"(\]]|$)#Di', function (array $m): string {
        return strtoupper($m[0]) === $m[0] ? $m[0] : delimite($m[0]);
    }, $s);
}

function delimite(string $name): string {
    return '`' . str_replace('`', '``', $name) . '`';
}

echo tryDelimite("SELECT * FROM users WHERE username=?;");

请问有人有什么想法吗?

【问题讨论】:

  • Lookbehinds (?&lt;=...)Javascript 的许多形式中不受支持。
  • 它是 Java,不是 JavaScript。
  • 然后改变你的标签,你把“Javascript”。
  • 我知道,这是 PHP 中正则表达式运行良好的唯一示例。我在 Java 中遇到了这个正则表达式的问题。
  • 欢迎吉野!请将此 PHP 代码明确声明为reference-solution in PHP。并将您自己的代码发布为minimal reproducible example(Java 中的尝试)。然后我们可以与它一起寻找解决方案。

标签: java regex pattern-matching matcher


【解决方案1】:

按如下方式进行:

public class Main {
    public static void main(String[] args) {
        // Tests
        String[] sqls = { 
                "SELECT * FROM users WHERE username=?;", 
                "SELECT * FROM Users WHERE username=?;",
                "SELECT * FROM `users` WHERE username=?;", 
                "SELECT * FROM `Users` WHERE username=?;" 
                };
        for (String sql : sqls) {
            System.out.println(sql.replace("`", "").replaceAll("(\\b[A-Z][a-z]+)|(\\b([a-z]+)\\b)", "`$0`"));
        }
    }
}

输出:

SELECT * FROM `users` WHERE `username`=?;
SELECT * FROM `Users` WHERE `username`=?;
SELECT * FROM `users` WHERE `username`=?;
SELECT * FROM `Users` WHERE `username`=?;

说明:

  1. sql.replace("`", "") 删除所有已经存在的反引号(通过用空字符串替换它们)以避免重复它们。
  2. \b 用于单词边界。
  3. [a-z]+ 仅用于小写字符。
  4. [A-Z][a-z]+ 表示大写字母后跟小写字母。
  5. | 用作or
  6. $0 用于整个匹配参数。

如有任何疑问/问题,请随时发表评论。

【讨论】:

  • 是的,它可以工作,但我有两个问题:1. 它在重复反引号,当已经设置 2. 并且它只在 word 是小写时才有效,但 word 可以像“用户名”
  • @yoshino - 我已经更新了我的答案以满足这两个要求。如有任何疑问/问题,请随时发表评论。
猜你喜欢
  • 2015-06-03
  • 2011-03-30
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
相关资源
最近更新 更多