Java正则表达式不匹配

huangapple go评论67阅读模式
英文:

Java regex doesn't match

问题

我有这个正则表达式:
#(?<=[^\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=?;");

有人有想法,请吗?

英文:

I have this regex:

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

and I'm trying to make SQL syntax pretty. For example from "SELECT * FROM users WHERE username=?;" to

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

This regex matching all words, which doesn't contain backticks. And in the match group I'm checking if is matched word uppercase. If is it true, then this word is skipped. And other words are added to the backticks. My problem is, that regex doesn't match nothing. I have similar code in the PHP, and it works there.

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=?;");

Does anyone have an idea, please?

答案1

得分: 0

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`"));
        }
    }
}

Output:

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

Explanation:

  1. sql.replace("", "")` removes all backticks (by replacing them with an empty string) if they are already present to avoid duplicating them.
  2. \b is used for word boundary.
  3. [a-z]+ is for only lowercase characters.
  4. [A-Z][a-z]+ is for a capital letter followed by lowercase letters.
  5. | is used as an or.
  6. $0 is used for the whole match argument.
英文:

Do it as follows:

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`"));
		}
	}
}

Output:

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

Explanation:

  1. sql.replace("`", "") removes all backticks (by replacing them with an empty string) if they are already present to avoid duplicating them.
  2. \b is used for word boundary.
  3. [a-z]+ is for only lowercase characters.
  4. [A-Z][a-z]+ is for a capital letter followed by lowercase letters.
  5. | is used as an or.
  6. $0 is used for the whole match argument.

huangapple
  • 本文由 发表于 2020年4月7日 00:50:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/61064851.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定