如何在vbs中使用regex模式来匹配前面或后面没有换行符或回车符的逗号?

How do I use a regex pattern in VBS to match commas not preceded or followed by a line feed or carriage return?

正如我理解的正则表达式一样,我认为这个模式应该在vbs中工作,在字符串中选取逗号,该字符串前面或后面是换行符或回车符,作为子匹配0或子匹配1(前两个模式组之一):

1
2
3
4
5
oRe.Pattern ="(,[

])|([

],)|(.{2},.{2})"

但是,在下面的字符串摘录中,submatch 2(第三个模式组)正在提取逗号,每个逗号前面都有一个回车:我要忽略这些逗号

这是图片中的代码:

1
2
3
4
5
6
7
SELECT
 di.QuestionSetID AS SectionID
,di.ScoreNBR AS SectionLowestTopBoxNBR
,di.AveragePercentileNBR AS SectionTopBoxPercentileRankNBR
,qdate.QuarterStartDTS AS SectionStartDTS
FROM NRCPicker.PatientSatisfaction.DimensionPercentile AS di
INNER JOIN (

有人知道为什么这些逗号会被选为子匹配2吗?

我的模式基于本文:http://www.rexegg.com/regex-best-trick.html。我还使用regex101.com来开发和测试这个模式。

我使用vbs通过使用split(string,",")创建数组来解析SQL脚本中的字段。在某些情况下,复合字段中包含逗号。我不想在这些逗号上拆分,因此在执行拆分操作之前,我将用空格替换这些逗号。然后,我的regex模式的结果将是只选取那些没有在回车/换行之前或之后的逗号,并用空格替换它们。

希望这能更好地说明我要做的事情:

以下是我的vbscript示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
SQLScript ="SELECT
 di.QuestionSetID AS SectionID
,di.ScoreNBR AS Section,LowestTopBoxNBR
,di.AveragePercentileNBR AS SectionTopBoxPercentileRankNBR
,qdate.Quarter,StartDTS AS Section,StartDTS
FROM NRCPicker.PatientSatisfaction.DimensionPercentile AS di
INNER JOIN ("
oRe.Pattern ="(,[

])|([

],)|(.{2},.{2})"
oLoadFields = oRe.Replace(SQLScript,"$1$2$3")

预期输出(仅当不在行首或行尾时用空格替换逗号):

1
2
3
4
5
6
7
oLoadFields ="SELECT
 di.QuestionSetID AS SectionID
,di.ScoreNBR AS Section LowestTopBoxNBR
,di.AveragePercentileNBR AS SectionTopBoxPercentileRankNBR
,qdate.Quarter StartDTS AS Section StartDTS
FROM NRCPicker.PatientSatisfaction.DimensionPercentile AS di
INNER JOIN ("


尝试如下:

1
(\S+?),(?=\S+)

我们利用这样一个事实,即所讨论的,总是被非空白\S包围。由于vbscript的regexp中没有(正的)lookback,所以我只需捕获前导部分并将其放回,而逗号本身被一个空格替换:"$1"

如果行尾或行首有多余的空白,也可以这样做。

演示

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Set re = New RegExp
re.Pattern ="(\S+?),(?=\S+)"
re.Global = True
Dim Input
Input ="SELECT" & vbCRLF & _
" di.QuestionSetID AS SectionID," & vbCRLF & _
" di.QuestionSetID AS SectionID2" & vbCRLF & _
",di.ScoreNBR AS Section,LowestTopBoxNBR" & vbCRLF & _
",di.AveragePercentileNBR AS SectionTopBoxPercentileRankNBR" & vbCRLF & _
",qdate.Quarter,StartDTS AS Section,StartDTS"& vbCRLF & _
"FROM NRCPicker.PatientSatisfaction.DimensionPercentile AS di" & vbCRLF & _
"INNER JOIN ("

msgbox re.Replace(Input,"$1")


如果vbs使用的引擎与js使用的引擎大致相同,则可以利用前瞻性断言和BOL/EOL锚。

在多行模式下:

找到(?!^),(?!$)。替换为空格

网址:https://regex101.com/r/lrxnvz/1

更新说明:注意,你不能只捕获逗号左右的内容,然后写回去因为可能有相邻的连续逗号。所以像(.),(.)这样的东西是行不通的。

示例1:它匹配"hellEDOCX1"(10),,,world",这将推进当前位置。超过下一个逗号,将永远不会与第二个逗号匹配。

示例2:它与"hello"、"EDOCX1"(11)world匹配,后者写回逗号。你可以在这里看到这种功能障碍https://regex101.com/r/u5cpgb/1


你只匹配第一个匹配项-也就是说,

SELECT
di.QuestionSetID AS SectionID
,
这里

但是,您没有看到任何效果,因为您在执行"$1$2$3"时,将它替换为捕获的相同文本。

如果不想在行距周围匹配逗号,而只替换行距中间的逗号,那么您要做的就是不将逗号锚定到[

]。您可以用插入符号来反转它:[^

],以便它匹配任何不是

的内容。然后,您需要相应地重新构造模式。

([^

]),([^

])将匹配任何不是逗号两边的字符,并将这些字符捕获到$1和$2中。要用空格替换逗号,您的替换字符串应该是:"$1 $2"

1
2
3
4
5
6
7
8
9
10
11
12
13
SQLScript ="SELECT
 di.QuestionSetID AS SectionID
,di.ScoreNBR AS Section,LowestTopBoxNBR
,di.AveragePercentileNBR AS SectionTopBoxPercentileRankNBR
,qdate.Quarter,StartDTS AS Section,StartDTS
FROM NRCPicker.PatientSatisfaction.DimensionPercentile AS di
INNER JOIN ("
oRe.Pattern ="([^

]),([^

])"
oLoadFields = oRe.Replace(SQLScript,"$1 $2")