VBScript用正则表达式替换特定值并修改文本文件

时间:2016-04-13 14:40:22

标签: vbscript

我知道有很多类似的问题,但我找不到合适的答案。我需要替换xml文件中以%开头和结尾的所有短语(例如%TEST%%TEST-NEW%

到目前为止,我有这些试用: 这是我的测试版,它在控制台中工作,但只有一行字符串

zone = "<test>%TEST%</test>"
MsgBox zone
'Setting the regex and cheking the matches
set regex = New RegExp
regex.IgnoreCase = True
regex.Global = True
regex.Pattern = "%.+%"
Set myMatches = regex.execute(zone)
For each myMatch in myMatches
Wscript.echo myMatch
result = Replace(zone,myMatch,"")
next
MsgBox result

但是当我尝试用这个文件做同样的事情时......

Dim objStream, strData, fields
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile("C:\test\test.xml")
strData = objStream.ReadText()
Wscript.echo strData

set regex = New RegExp
regex.IgnoreCase = True
regex.Global = True
regex.Pattern = "%.+%"
Set myMatches = regex.execute(strData)
For each myMatch in myMatches
Wscript.echo myMatch
result = Replace(strData,myMatch,"")
next
Wscript.echo result

...第一个echo正确返回文件的包含,然后循环中的第二个echo回显我需要替换的所有匹配,但最后一个echo返回与第一个相同的结果(没有被替换)

xml看起来像这样(例如):

<script>%TEST%</script>
<value>%VALUE%</value>
<test>%TEST%</test>

P.S。我需要遍历特定文件夹中的xml文件并替换上面的短语。有人可以帮忙吗?

适用于我的最终脚本(非常感谢Tomalak):

Option Explicit

Dim path, doc, node, placeholder,srcFolder,FSO,FLD,fil

Set placeholder = New RegExp
placeholder.Pattern = "%[^%]+%"
placeholder.Global = True


srcFolder = "C:\test"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FLD = FSO.GetFolder(srcFolder)

For each fil In FLD.Files

    if LCase(FSO.GetExtensionName(fil.Name)) = "xml" Then

            path = "C:\test\" & fil.Name

            ' 1. parse the XML into a DOM
            Set doc = LoadXmlDoc(path)

            ' 2. select and modify DOM nodes
            For Each node In doc.selectNodes("//text()|//@*")
                node.nodeValue = SubstitutePlaceholders(node.nodeValue)
            Next

            ' 3. save modified DOM back to file
            doc.save path
    End If

Next            
' --------------------------------------------------------------------------

Function LoadXmlDoc(path)
    Set LoadXmlDoc = CreateObject("MSXML2.DomDocument.6.0")

    LoadXmlDoc.async = False
    LoadXmlDoc.load path
    If LoadXmlDoc.parseError.errorCode <> 0 Then
        WScript.Echo "Error in XML file."
        WScript.Echo LoadXmlDoc.parseError.reason
        WScript.Quit 1
    End If
End Function
' --------------------------------------------------------------------------

Function SubstitutePlaceholders(text)
    Dim match

    For Each match In placeholder.Execute(text)
        text = Replace(text, match, GetReplacement(match))
    Next

    SubstitutePlaceholders = text
End Function
' --------------------------------------------------------------------------

Function GetReplacement(placeholder)
    Select Case placeholder
        Case "%TEST%": GetReplacement = "new value"
        Case "%BLA%": GetReplacement = "other new value"
        Case Else: GetReplacement = placeholder
    End Select
End Function
' --------------------------------------------------------------------------

1 个答案:

答案 0 :(得分:3)

永远不要在XML文件上使用正则表达式。

使用XML解析器。它会更简单,代码更容易阅读,最重要的是:它不会破坏XML。

以下是如何以正确的方式修改XML文档。

Option Explicit

Dim path, doc, node, placeholder

Set placeholder = New RegExp
placeholder.Pattern = "%[^%]+%"
placeholder.Global = True

path = "C:\path\to\your.xml"

' 1. parse the XML into a DOM
Set doc = LoadXmlDoc(path)

' 2. select and modify DOM nodes
For Each node In doc.selectNodes("//text()|//@*")
    node.nodeValue = SubstitutePlaceholders(node.nodeValue)
Next

' 3. save modified DOM back to file
doc.save path
' --------------------------------------------------------------------------

Function LoadXmlDoc(path)
    Set LoadXmlDoc = CreateObject("MSXML2.DomDocument.6.0")

    LoadXmlDoc.async = False
    LoadXmlDoc.load path
    If LoadXmlDoc.parseError.errorCode <> 0 Then
        WScript.Echo "Error in XML file."
        WScript.Echo LoadXmlDoc.parseError.reason
        WScript.Quit 1
    End If
End Function
' --------------------------------------------------------------------------

Function SubstitutePlaceholders(text)
    Dim match

    For Each match In placeholder.Execute(text)
        text = Replace(text, match, GetReplacement(match))
    Next

    SubstitutePlaceholders = text
End Function
' --------------------------------------------------------------------------

Function GetReplacement(placeholder)
    Select Case placeholder
        Case "%TEST%": GetReplacement = "new value"
        Case "%BLA%": GetReplacement = "other new value"
        Case Else: GetReplacement = placeholder
    End Select
End Function
' --------------------------------------------------------------------------

XPath表达式//text()|//@*以所有文本节点和所有属性节点为目标。必要时使用不同的XPath表达式。 (我不会在这里介绍XPath基础知识,有很多资源可供学习。)

当然,此解决方案使用正则表达式,但它对XML结构包含的文本值执行此操作,而不是在XML结构本身上执行。这是一个至关重要的区别。