【发布时间】:2023-03-04 08:59:02
【问题描述】:
我有大量从我管理的服务器记录的 T-SQL 语句。我正在尝试将它们归结为每个实例。
这是其中之一:
SELECT TBLLANGUAGE.NAME AS NAME1, TBLLANGUAGE_1.NAME AS NAME2,
TBLLANGUAGELANGUAGE.LNGFKCHILD, TBLLANGUAGELANGUAGE.LNGFKPARENT,
TBLLANGUAGELANGUAGE.STYLE, TBLLANGUAGELANGUAGE.EXTENT,
TBLLANGUAGELANGUAGE.NATURE, TBLSOURCE.TXTTITLE, TBLSOURCE_1.TXTTITLE AS
SURTITLE FROM ((((TBLLANGUAGE LEFT JOIN TBLLANGUAGELANGUAGE ON
TBLLANGUAGE.ID = TBLLANGUAGELANGUAGE.LNGFKPARENT) LEFT JOIN TBLLANGUAGE
AS TBLLANGUAGE_1 ON TBLLANGUAGELANGUAGE.LNGFKCHILD = TBLLANGUAGE_1.ID)
LEFT JOIN TBLLANGLANGSOURCE ON TBLLANGUAGELANGUAGE.IDLANGLINK =
TBLLANGLANGSOURCE.LNGFKLANGLINK) LEFT JOIN TBLSOURCE ON
TBLLANGLANGSOURCE.LNGFKSOURCE = TBLSOURCE.IDSOURCE) LEFT JOIN TBLSOURCE
AS TBLSOURCE_1 ON TBLSOURCE.LNGPARTOF = TBLSOURCE_1.IDSOURCE WHERE
(((TBLLANGUAGELANGUAGE.LNGFKPARENT) = 8687)) OR
(((TBLLANGUAGELANGUAGE.LNGFKCHILD) = 8687)) ORDER BY
IIF(TBLLANGUAGELANGUAGE.LNGFKPARENT = 8687,'B','A'), TBLLANGUAGE.NAME,
TBLLANGUAGE_1.NAME;
我想将其转换为 JavaScript 正则表达式,将\d 的数字替换为'.*',将撇号之间的内容替换为'.*'。
到目前为止,我在 Deno 方面已经做到了这一点:
function getPattern(text: string): string {
text = text.replace(/\(/g, "\\x28")
.replace(/\)/g, "\\x29")
.replace(/\$/g, "\\x24")
.replace(/\^/g, "\\x5e")
.replace(/\./g, "\\x2e")
.replace(/\*/g, "\\x2a")
.replace(/\[/g, "\\x5b")
.replace(/\]/g, "\\x5d")
.replace(/\?/g, "\\x3f");
[ "\\<\s\\>", "\\<", "\\<=", "=", "\\>=", "\\>"].forEach((op) => {
const numberPattern = new RegExp(`\\s${op}\\s(\\d+)`, "g");
text.match(numberPattern)?.forEach((e) => {
text = text.replace(e, ` ${op} \\d+`);
});
});
//const textPattern = /'[^']*'\s/g;
const textPattern = /\s*'.*'\s*/g;
text.match(textPattern)?.forEach((e) => {
//const eLength = e.length;
text = text.replace(e, "\\s*'.*'\\s*");
});
return text; //.replace(/\</g, "\\x3c")
//.replace(/\>/g, "\\x3e");
}
这会将上述语句呈现为
SELECT TBLLANGUAGE\x2eNAME AS NAME1, TBLLANGUAGE_1\x2eNAME AS NAME2,
TBLLANGUAGELANGUAGE\x2eLNGFKCHILD, TBLLANGUAGELANGUAGE\x2eLNGFKPARENT,
TBLLANGUAGELANGUAGE\x2eSTYLE, TBLLANGUAGELANGUAGE\x2eEXTENT,
TBLLANGUAGELANGUAGE\x2eNATURE, TBLSOURCE\x2eTXTTITLE,
TBLSOURCE_1\x2eTXTTITLE AS SURTITLE FROM \x28\x28\x28\x28TBLLANGUAGE
LEFT JOIN TBLLANGUAGELANGUAGE ON TBLLANGUAGE\x2eID =
TBLLANGUAGELANGUAGE\x2eLNGFKPARENT\x29 LEFT JOIN TBLLANGUAGE AS
TBLLANGUAGE_1 ON TBLLANGUAGELANGUAGE\x2eLNGFKCHILD =
TBLLANGUAGE_1\x2eID\x29 LEFT JOIN TBLLANGLANGSOURCE ON
TBLLANGUAGELANGUAGE\x2eIDLANGLINK =
TBLLANGLANGSOURCE\x2eLNGFKLANGLINK\x29 LEFT JOIN TBLSOURCE ON
TBLLANGLANGSOURCE\x2eLNGFKSOURCE = TBLSOURCE\x2eIDSOURCE\x29 LEFT JOIN
TBLSOURCE AS TBLSOURCE_1 ON TBLSOURCE\x2eLNGPARTOF =
TBLSOURCE_1\x2eIDSOURCE WHERE
\x28\x28\x28TBLLANGUAGELANGUAGE\x2eLNGFKPARENT\x29 = \d+\x29\x29 OR
\x28\x28\x28TBLLANGUAGELANGUAGE\x2eLNGFKCHILD\x29 = \d+\x29\x29 ORDER
BY IIF\x28TBLLANGUAGELANGUAGE\x2eLNGFKPARENT = \d+,\s*'.*'\s*\x29,
TBLLANGUAGE\x2eNAME, TBLLANGUAGE_1\x2eNAME;
我正在将各种组件转换为它们的 \xnn 表单,因为我阅读文档的方式显然 new RegExp() 不够聪明,无法看到嵌入的 ( 并且不认为我在定义一个组在正则表达式中。也就是说,光说似乎还不够
const pattern = new RegExp("SELECT TBLLANGUAGE.NAME (etcetera)","gi");
我是不是读错了文档,有没有更好的方法?不,我不想编写 T-SQL 解析器,除非有非常非常好的理由。
稍后
通过使用不同的模式匹配方法,我基本上解决了我的问题。请在DEV 上查看Extracting example SQL statements from a log。
【问题讨论】:
-
仅供参考,我强烈建议您养成在写作时使用换行符和空格的习惯。 900 多个字符长的单行代码是出了名的难以阅读。
-
这不是 RegExp 构造函数的问题,而是发生了 两个 解析操作的事实:第一个,当字符串语法解释字符串(它不知道它是正则表达式),并且该语法 also 在该上下文中使用反斜杠作为转义序列。只有这样,解析后的字符串值才会传递给构造函数,构造函数将开始 second 解析。
-
已采纳建议。帖子更新了。谢谢你,@Larnu
-
我的回答好运吗?
-
@MonkeyZeus 它几乎可以工作。我正在创建两个版本的 Deno 脚本,一个使用您的技术,另一个使用更简单的标记化方法。我希望将两者都放在 dev.to 上。我可能会给你“打勾”,但实际上使用的是标记器方法。
标签: javascript sql-server regex tsql deno