使用正则表达式替换 TextArea 中的文本正在创建新行
Replacing Text within TextArea using Regular Expression is creating new lines
我正在创建一个 HTML 应用程序,允许用户自由输入 textarea
,然后将正则表达式模式输入一个 input
框和一个替换字符串进入第二个 input
框。当用户按下一个按钮时,一个 VBScript 序列运行,它接受用户输入,创建一个正则表达式并用字符串替换模式。我的问题是,当用户选择一行的结尾时,即 $
的模式,替换字符串被添加到每一行并且 inbetween 每行也是如此。
例如下面的文字:
Test
Test
Test
如果输入 @
的替换字符串,将输出为:
Test@
@
Test@
@
Test@
如何防止 "additional" 行出现在输出中?首先是什么原因造成的?
申请代码如下:
<!doctype html>
<head>
<hta:application
id="regexpengine"
applicationname="RegExpEngine"
icon="S:\Technical Projects\TechProd VB Projects\SPF Creator\SPF Creator\tools.ico"
singleinstance="yes"
border="thick"
borderstyle="complex"
scroll="yes"
maximizebutton="no"
version="0.1" />
<title>Regular Expression Engine</title>
<meta http-equiv="x-ua-compatible" content="ie=8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<script language="VBScript">
' Set Global Variables
'Core Objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Input/Event Variables
strInput = "No User Input"
strExp = Empty
strReplace = Empty
strOutput = Empty
strUserFunction = Empty
strInstruction = Empty
strUserConfirmedAction = Empty
strOriginalInput = Empty
'Custom Objects
objRecord = False
objGUIOption = "Type"
Sub Window_onLoad()
'Load Previously Entered Data if Available
'Check that RAWFiles.txt exists and load any contained text
'If objFSO.FileExists("C:\Temp\RAWFiles.txt") Then
'' Set objFileSize = objFSO.GetFile("C:\Temp\RAWFiles.txt")
'' If objFileSize.size > 0 Then
'' Set objFile=objFSO.OpenTextFile("C:\Temp\RAWFiles.txt",1)
'' strFileList=objFile.ReadAll
'' document.all.FileList.value=strFileList
'' objFile.Close
'' End If
'End If
'Load Previous Folder Values if Available
'If objFSO.FileExists("C:\Temp\FolderLocation.txt") Then
'' Set objFileSize = objFSO.GetFile("C:\Temp\FolderLocation.txt")
'' If objFileSize.size > 0 Then
'' Set objFile=objFSO.OpenTextFile("C:\Temp\FolderLocation.txt",1)
'' strInputfolder=objFile.ReadLine
'' strOutputfolder=objFile.ReadLine
'' document.all.inputFolder.value=strInputfolder
'' document.all.outputFolder.value=strOutputfolder
'' objFile.Close
'' End If
'End If
'Force Window Size & Position
window.resizeTo 885,750
window.moveTo (screen.width - 885)/2, (screen.height - 750)/2
'Hide File Input Option Until Selected
document.all.selectFolder.style.display = "none"
document.all.fileContents.style.display = "none"
End Sub
Sub UpdateMessage(strMessage,objType)
'Update Message Area for Errors & User Decisions
If objType = 2 Then
LogArea.innerHTML = "<span class='error'>Error: " & strMessage & "</span><br>"
Else
LogArea.innerHTML = "<span class='update'>Message: " & strMessage & "</span><br>"
End If
End Sub
Sub RunExpression
'Take User Input & Run Expression Against File
'Set Regular Expression
Set objRegExp = New RegExp
If strUserFunction="Replace" Then
'Pattern for Replace Function - finds the first matched instance and then terminates
With objRegExp
.Pattern = strExp
.IgnoreCase = False
.Global = False
End With
Elseif strUserFunction="ReplaceAll" OR strUserFunction="Find" Then
'Pattern for ReplaceAll & Find Functions - finds every matched instance
With objRegExp
.Pattern = strExp
.IgnoreCase = False
.Global = True
.Multiline = True
End With
End If
'Reset Output String
strOutput = Empty
'Perform User Selected Function
If strUserFunction = "Replace" OR strUserFunction = "ReplaceAll" Then
'Perform Replace - if the user input errors then capture the reason and end sequence
On Error Resume Next
'Replace on strReplace ensures that users can add in newlines using a standard \n
strOutput = objRegExp.Replace(strInput,Replace(strReplace,"\n",vbNewLine))
If Err.Number <> 0 Then
Msgbox "Regular Expression Not Recognised",16,"Incorrect Syntax"
Err.Clear
UpdateMessage "Regular Expression Not Recognised - Incorrect Syntax - Instruction Failed",2
strInstruction = Empty
Exit Sub
End If
Elseif strUserFunction = "Find" Then
Set objFind = objRegExp.Execute(strInput)
strOutput = "Total Matches: " & objFind.Count & vbCRLF
For Each Match in objFind
strOutput = strOutput & "Matched: " & Match.Value & vbCRLF
Next
'Prevent Find Instructions from Being Committed
strInstruction = Empty
Else
UpdateMessage "Run Attempted Without User Input - Run Terminated",2
strInstruction = Empty
Exit Sub
End If
'Write the Output to the Application Window - if the string has been replaced completely with a null value, output {EMPTY}
If strOutput = "" Then
expOutput.innerHTML = "{EMPTY}"
Else
document.getElementById("expOutput").appendChild(document.createTextNode(strOutput))
End If
'Inform User & Update if Recording
If objRecord = True Then
UpdateInput
UpdateMessage "Performed Instruction Succesfully - Input Updated",1
expOutput.innerHTML = "{RECORDING}"
Else
UpdateMessage "Performed Instruction Successfully",1
End If
End Sub
Sub GetUserInput(strFunction)
'Pull In User Input from Interface
'Reset Error Message
expOutput.innerHTML = ""
'Determine Which Function was Requested (which button was pressed)
strUserFunction = strFunction
'Set User Input Data
If userInputMethod.selectInputMethod(0).checked Then
If Not userInput.Value = "" Then
strInput = userInput.Value
Else
UpdateMessage "Free Typed Input is Selected but Textarea is Blank",2
Exit Sub
End If
Elseif userInputMethod.selectInputMethod(1).checked Then
If Not fileContents.Value = "" Then
strInput = fileContents.Value
Else
UpdateMessage "Selected File is Blank",2
Exit Sub
End If
Else
Exit Sub
End If
'Set Expression
If Not inputExp.Value = "" Then
strExp = inputExp.Value
Else
UpdateMessage "No Expression Entered",2
Exit Sub
End If
'Set Replace
If Not replaceExp.Value = "" Then
strReplace = replaceExp.Value
Else
strReplace = ""
End If
'Save Instruction
If objRecord = True Then
If Not strInstruction = Empty Then
strInstruction = strInstruction & vbCRLF & strUserFunction & "," & strExp & "," & strReplace
Else
strInstruction = strUserFunction & "," & strExp & "," & strReplace
End If
Else
strInstruction = strUserFunction & "," & strExp & "," & strReplace
End If
RunExpression
End Sub
Sub ChooseTextArea
'Display User Input Textarea
'Update GUI
document.all.userInput.style.display="block"
document.all.selectFolder.style.display="none"
document.all.fileContents.style.display = "none"
'Set Choice
objGUIOption = "Type"
End Sub
Sub ChooseFile
'Display File Input
'Update GUI
document.all.userInput.style.display="none"
document.all.selectFolder.style.display="inline"
If Not fileContents.Value = "" Then
document.all.fileContents.style.display = "block"
End If
'Set Choice
objGUIOption = "File"
End Sub
Sub UploadSelectedFile
'Check User Selected File Exists & Load Contained Text
'Reset Error Message
expOutput.innerHTML = ""
'Get User Input & Sanitise
objFilePath = fileInput.Value
objFilePath = Replace(objFilePath,chr(34),"")
'Extract Data from File
If objFSO.FileExists(objFilePath) Then
Set objFileSize = objFSO.GetFile(objFilePath)
If objFileSize.size > 0 Then
Set objFile=objFSO.OpenTextFile(objFilePath,1)
strFileContents=objFile.ReadAll
document.all.fileContents.value=strFileContents
objFile.Close
Else
UpdateMessage "Selected Filed is Blank",2
Exit Sub
End If
Else
UpdateMessage "Input File Does Not Exist",2
Exit Sub
End If
'Make Textarea Visible
document.all.fileContents.style.display = "block"
End Sub
Sub CommitInstruction
'Save Current Instruction to Recipe
'Check that Instruction Exists
If strInstruction = Empty Then
UpdateMessage "Instruction is Blank or Does Not Exist",2
Exit Sub
End If
'Check whether a Recipe Exists
If objFSO.FileExists("C:\Temp\Temp_Recipe.txt") Then
Set objRecipe = objFSO.GetFile("C:\Temp\Temp_Recipe.txt")
'Check the Recipe Contains Instructions
If objRecipe.size > 0 And strUserConfirmedAction = "" Then
'Check How User Wants to Interact with Present Recipe - Overwrite or Amend?
userConfirm = Msgbox("A partial Recipe already exists. Should it be deleted?",35,"How to Proceed?")
'User Decision: Overwrite (Yes - 6) or Amend (No - 7)
If userConfirm = 6 Then
strUserConfirmedAction = "Overwrite"
Elseif userConfirm = 7 Then
'Request Further User Input
userConfirm = Msgbox("Amend the partial Recipe with new Instructions?",33,"How to Proceed?")
If userConfirm = 1 Then
strUserConfirmedAction = "Amend"
Elseif userConfirm = 2 Then
'Cancel Operation & Open Temp Folder
Msgbox "Delete Current Recipe & Try Again",64,"Operation Cancelled"
userConfirm = Empty
UpdateMessage "Commit Cancelled by User",2
Set objShell = CreateObject("shell.application")
objShell.Open("C:\Temp")
Exit Sub
End If
Elseif userConfirm = 2 Then
UpdateMessage "Commit Cancelled by User",2
Exit Sub
End If
Elseif strUserConfirmedAction = "" Then
'If Recipe is Blank, Assume Amending
strUserConfirmedAction = "Amend"
End If
Else
'Set Field so that Recipe will be Created
strUserConfirmedAction = "Amend"
End If
'Write Instruction to Recipe
If strUserConfirmedAction = "Overwrite" Then
'Overwrite Current Recipe & Set to Amend for Further Commits
Set objFile = objFSO.OpenTextFile("C:\Temp\Temp_Recipe.txt",2,1)
objFile.WriteLine strInstruction
objFile.Close
strUserConfirmedAction = "Amend"
Elseif strUserConfirmedAction = "Amend" Then
'Append Current Instruction to Recipe
Set objFile = objFSO.OpenTextFile("C:\Temp\Temp_Recipe.txt",8,1)
objFile.WriteLine strInstruction
objFile.Close
End If
'Clear Instruction
strInstruction = Empty
'Update Input
UpdateInput
UpdateMessage "Instruction Saved and Input Updated",1
End Sub
Sub DeleteRecipe
'User Requests to Delete Current Recipe
'Ensure User Confirmation is Empty
strUserDelete = Empty
'Check that a Recipe Exists
If objFSO.FileExists("C:\Temp\Temp_Recipe.txt") Then
'Request User Confirmation
strUserDelete = Msgbox("Delete Unsaved Recipe Permanently?",17,"Delete File Permanently")
Else
UpdateMessage "No Recipe Found - Cannot Delete",2
Exit Sub
End If
'Delete Recipe
If strUserDelete = 1 Then
objFSO.DeleteFile("C:\Temp\Temp_Recipe.txt")
UpdateMessage "Partial Recipe Deleted",1
Else
UpdateMessage "User Cancelled Delete Operation",2
End If
End Sub
Sub PreviewRecipe
'Preview Current Recipe
'Ensure Values are Empty
strRecipePreview = Empty
'Check that a Recipe Exists
If Not objFSO.FileExists("C:\Temp\Temp_Recipe.txt") Then
UpdateMessage "Recipe Cannot Be Found",2
Exit Sub
Else
Set objRecipe = objFSO.GetFile("C:\Temp\Temp_Recipe.txt")
If Not objRecipe.size > 0 Then
strRecipePreview = "{EMPTY}"
UpdateMessage "Recipe is Currently Blank",1
End If
End If
'Retrieve & Display Recipe
Set objRecipe = objFSO.OpenTextFile("C:\Temp\Temp_Recipe.txt",1)
If strRecipePreview = Empty Then
strRecipePreview = objRecipe.ReadAll
End If
Msgbox strRecipePreview,64,"Recipe Preview:"
End Sub
Sub RecordInstructions
'Continuously Commit Instructions as Each if Run by User
'Reset Button State & User Input
strButtonPressed = False
strUserCommit = Empty
'Start Recording
If objRecord = False And strButtonPressed = False Then
If Not strInstruction = Empty Then
'Request User Input - Delete or Keep Current Instruction?
strUserCommit = Msgbox("Commit Current Instruction?",35,"Instruction Already Exists")
If strUserCommit = 6 Then
CommitInstruction
'If Commit is Cancelled by User then Don't Continue
If Not strInstruction = Empty Then
Exit Sub
End If
Elseif strUserCommit = 7 Then
strInstruction = Empty
Elseif strUserCommit = 2 Then
Exit Sub
End If
End If
objRecord = True
strButtonPressed = True
UpdateMessage "Recording Instructions Initiated",1
runRecord.innerHTML = "Stop (<span class='quickKey'>d</span>)"
End If
'Stop Recording
If objRecord = True And strButtonPressed = False Then
If Not strInstruction = Empty Then
'Request User Input - Delete or Commit Recording?
strUserCommit = Msgbox("Commit Recorded Instructions?",35,"Recording Ended")
If strUserCommit = 6 Then
CommitInstruction
'If Commit is Cancelled by User then Don't Continue
If Not strInstruction = Empty Then
Exit Sub
End If
Elseif strUserCommit = 7 Then
strInstruction = Empty
Elseif strUserCommit = 2 Then
Exit Sub
End If
End If
objRecord = False
strButtonPressed = True
UpdateMessage "Recording Instructions Terminated",1
runRecord.innerHTML = "Recor<span class='quickKey'>d</span>"
End If
End Sub
Sub UpdateInput
'Refresh the Input After a Commit to Allow Continual Editing
'Save Original Text on First Commit
If strOriginalInput = Empty Then
strOriginalInput = strInput
End If
'Update Input
strInput = strOutput
'Update GUI
If objGUIOption = "Type" Then
userInput.innerHTML = strInput
Else
fileContents.innerHTML = strInput
End If
expOutput.innerHTML = ""
End Sub
Sub Test
Msgbox(strOutput)
End Sub
</script>
<style>
body {
margin: 0 20px;
padding: 0;
font-family: "Segoe UI", Geneva, sans-serif;
background: #f3f3f3;
overflow: auto;
}
h1 {
font-size: 15pt;
text-align: center;
margin-bottom: 0;
color: #273754;
}
pre {
line-height: 8px;
font-family: "Courier New", Courier, monospace, sans-serif;
background: #ffffff;
height: 150px;
overflow: auto;
padding: 10px;
}
button {
padding: 10px;
font-size: 16px;
font-weight: 100;
color: #fff;
background: #777d84;
border: 0;
}
button.select {
padding: 5px 10px;
font-size: 12px;
margin: 0 1px;
}
button:hover {
background: #646a70;
}
input[type=text] {
height: 20px;
width: 72%;
}
textarea {
overflow: auto;
}
.error {
color: #e22b2b;
}
.folderInput {
width: 85%;
margin: auto;
}
.folderSelect {
margin:0 20px 0 0;
display: block;
float: left;
width: 100px;
}
.buttonContainer {
margin: auto;
text-align: center;
}
input[type=button].featureButton {
width: 100px;
font-size: 12px;
padding: 5px 10px;
}
span.quickKey {
text-decoration: underline;
}
#logArea {
height: 8px;
}
#retrieveRAW {
margin-top: 20px;
font-weight: bold;
background: #4a8e0b;
}
.right {
float: right;
}
</style>
<body>
<div>
<H1>Test Regular Expression</H1>
<p>
<form id="userInputMethod">
<span class="option">Free Type Input:</span>
<input name="selectInputMethod" type="radio" onClick="ChooseTextArea" checked>
<span class="option">Select File Input:</span>
<input name="selectInputMethod" type="radio" onClick="ChooseFile">
</form>
<textarea name="userInput" rows=10 cols=100></textarea>
<span id="selectFolder"><input type="text" id="fileInput" size=100><button id="runFolder" onClick="UploadSelectedFile">Submit</button></span>
</p>
<p>
<textarea name="fileContents" rows=10 cols=100></textarea>
</p>
</div>
<div>
<p>
Regular Expression to Test:<br>
<input type="text" id="inputExp" size=100>
</p>
<p>
Replace With:<br>
<input type="text" id="replaceExp" size=100>
</p>
</div>
<div>
<button id="runReplace" onClick="GetUserInput('Replace')" accessKey="r"><span class="quickKey">R</span>eplace</button>
<button id="runReplaceAll" onClick="GetUserInput('ReplaceAll')" accessKey="a">Replace <span class="quickKey">A</span>ll</button>
<button id="runFind" onClick="GetUserInput('Find')" accessKey="f"><span class="quickKey">F</span>ind</button>
<span class="right">
<button id="runCommit" onClick="CommitInstruction" accessKey="c"><span class="quickKey">C</span>ommit</button>
<button id="runRecord" onClick="RecordInstructions" accessKey="d">Recor<span class="quickKey">d</span></button>
<button id="runPreview" onClick="PreviewRecipe" accessKey="v">Pre<span class="quickKey">v</span>iew</button>
<button id="runDelete" onClick="DeleteRecipe">Delete</button>
<button id="runTest" onClick="Test" accessKey="t"><span class="quickKey">T</span>est</button>
<button id="runCook" onClick="Test" accessKey="k">Coo<span class="quickKey">k</span></button>
</span><br><br>
</div>
<div>
<pre id="logArea">Ready to Begin...</pre>
</div>
<div>
<pre id="expOutput"></pre>
</div>
</body>
</html>
Pattern Property documentation 关于 $
模式字符太简短了:
$
Matches the end of input.
有关更详细的规范,请阅读 Regular Expression Programming (Scripting) 文章(向下滚动到 Flags 段落)。简而言之:
Flags
In the JScript regular expression /abc/gim
, the g
specifies the
global flag, the i
specifies the ignore case flag, and the m
specifies the multiline flag.
In VBScript, you can specify these flags by setting the equivalent
properties to True
.
…
Multiline
^
matches positions following a \n
or \r
, and
$
matches positions before \n
or \r
.
实际上、$
匹配\n
之前的位置(LF)和 在 \r
之前 (CR).
案例说明:
- if 输入字段是 TestCRLFTestCRLF测试
- 正则表达式模式是
$
- 和替换字段为
@
- then
Replace All
action results to Test@CR@LF测试@CR@LF测试@
解决方案(通常不正确):
- 使用
\b$
模式(它不会匹配空行的结尾或带有任何尾随白色 space 的行的结尾,包括 space、制表符等)
- 在 替换为 字段中使用
\r\n
模式 和 尾随 \n
(它不会匹配最后一个不以 \r\n
结尾的行,即 CRLF).
出于调试目的,我使用以下代码存根改进了第 147 行的 HTA 代码:
Else
UpdateMessage "Performed Instruction Successfully",1
If strUserFunction <> "Find" Then
MsgBox HexScan(strInput , "strInput" ) _
& HexScan(strReplace, "strReplace") _
& HexScan(strOutput , "strOutput" ), vbOKOnly, "hexadecimals"
End If
End If
End Sub
Function HexScan( Byval strStr, strHead)
HexScan = strHead & Space(1) & CStr( Len(strStr)) & vbNewLine & "hex "
For ii = 1 To Len(strStr)
HexScan = HexScan & Right( "0" & Hex(Asc(Mid(strStr,ii,1))),2) & " "
Next
HexScan = HexScan & vbNewLine
End Function
Sub GetUserInput(strFunction)
'Pull In User Input from Interface
我正在创建一个 HTML 应用程序,允许用户自由输入 textarea
,然后将正则表达式模式输入一个 input
框和一个替换字符串进入第二个 input
框。当用户按下一个按钮时,一个 VBScript 序列运行,它接受用户输入,创建一个正则表达式并用字符串替换模式。我的问题是,当用户选择一行的结尾时,即 $
的模式,替换字符串被添加到每一行并且 inbetween 每行也是如此。
例如下面的文字:
Test
Test
Test
如果输入 @
的替换字符串,将输出为:
Test@
@
Test@
@
Test@
如何防止 "additional" 行出现在输出中?首先是什么原因造成的?
申请代码如下:
<!doctype html>
<head>
<hta:application
id="regexpengine"
applicationname="RegExpEngine"
icon="S:\Technical Projects\TechProd VB Projects\SPF Creator\SPF Creator\tools.ico"
singleinstance="yes"
border="thick"
borderstyle="complex"
scroll="yes"
maximizebutton="no"
version="0.1" />
<title>Regular Expression Engine</title>
<meta http-equiv="x-ua-compatible" content="ie=8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<script language="VBScript">
' Set Global Variables
'Core Objects
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Input/Event Variables
strInput = "No User Input"
strExp = Empty
strReplace = Empty
strOutput = Empty
strUserFunction = Empty
strInstruction = Empty
strUserConfirmedAction = Empty
strOriginalInput = Empty
'Custom Objects
objRecord = False
objGUIOption = "Type"
Sub Window_onLoad()
'Load Previously Entered Data if Available
'Check that RAWFiles.txt exists and load any contained text
'If objFSO.FileExists("C:\Temp\RAWFiles.txt") Then
'' Set objFileSize = objFSO.GetFile("C:\Temp\RAWFiles.txt")
'' If objFileSize.size > 0 Then
'' Set objFile=objFSO.OpenTextFile("C:\Temp\RAWFiles.txt",1)
'' strFileList=objFile.ReadAll
'' document.all.FileList.value=strFileList
'' objFile.Close
'' End If
'End If
'Load Previous Folder Values if Available
'If objFSO.FileExists("C:\Temp\FolderLocation.txt") Then
'' Set objFileSize = objFSO.GetFile("C:\Temp\FolderLocation.txt")
'' If objFileSize.size > 0 Then
'' Set objFile=objFSO.OpenTextFile("C:\Temp\FolderLocation.txt",1)
'' strInputfolder=objFile.ReadLine
'' strOutputfolder=objFile.ReadLine
'' document.all.inputFolder.value=strInputfolder
'' document.all.outputFolder.value=strOutputfolder
'' objFile.Close
'' End If
'End If
'Force Window Size & Position
window.resizeTo 885,750
window.moveTo (screen.width - 885)/2, (screen.height - 750)/2
'Hide File Input Option Until Selected
document.all.selectFolder.style.display = "none"
document.all.fileContents.style.display = "none"
End Sub
Sub UpdateMessage(strMessage,objType)
'Update Message Area for Errors & User Decisions
If objType = 2 Then
LogArea.innerHTML = "<span class='error'>Error: " & strMessage & "</span><br>"
Else
LogArea.innerHTML = "<span class='update'>Message: " & strMessage & "</span><br>"
End If
End Sub
Sub RunExpression
'Take User Input & Run Expression Against File
'Set Regular Expression
Set objRegExp = New RegExp
If strUserFunction="Replace" Then
'Pattern for Replace Function - finds the first matched instance and then terminates
With objRegExp
.Pattern = strExp
.IgnoreCase = False
.Global = False
End With
Elseif strUserFunction="ReplaceAll" OR strUserFunction="Find" Then
'Pattern for ReplaceAll & Find Functions - finds every matched instance
With objRegExp
.Pattern = strExp
.IgnoreCase = False
.Global = True
.Multiline = True
End With
End If
'Reset Output String
strOutput = Empty
'Perform User Selected Function
If strUserFunction = "Replace" OR strUserFunction = "ReplaceAll" Then
'Perform Replace - if the user input errors then capture the reason and end sequence
On Error Resume Next
'Replace on strReplace ensures that users can add in newlines using a standard \n
strOutput = objRegExp.Replace(strInput,Replace(strReplace,"\n",vbNewLine))
If Err.Number <> 0 Then
Msgbox "Regular Expression Not Recognised",16,"Incorrect Syntax"
Err.Clear
UpdateMessage "Regular Expression Not Recognised - Incorrect Syntax - Instruction Failed",2
strInstruction = Empty
Exit Sub
End If
Elseif strUserFunction = "Find" Then
Set objFind = objRegExp.Execute(strInput)
strOutput = "Total Matches: " & objFind.Count & vbCRLF
For Each Match in objFind
strOutput = strOutput & "Matched: " & Match.Value & vbCRLF
Next
'Prevent Find Instructions from Being Committed
strInstruction = Empty
Else
UpdateMessage "Run Attempted Without User Input - Run Terminated",2
strInstruction = Empty
Exit Sub
End If
'Write the Output to the Application Window - if the string has been replaced completely with a null value, output {EMPTY}
If strOutput = "" Then
expOutput.innerHTML = "{EMPTY}"
Else
document.getElementById("expOutput").appendChild(document.createTextNode(strOutput))
End If
'Inform User & Update if Recording
If objRecord = True Then
UpdateInput
UpdateMessage "Performed Instruction Succesfully - Input Updated",1
expOutput.innerHTML = "{RECORDING}"
Else
UpdateMessage "Performed Instruction Successfully",1
End If
End Sub
Sub GetUserInput(strFunction)
'Pull In User Input from Interface
'Reset Error Message
expOutput.innerHTML = ""
'Determine Which Function was Requested (which button was pressed)
strUserFunction = strFunction
'Set User Input Data
If userInputMethod.selectInputMethod(0).checked Then
If Not userInput.Value = "" Then
strInput = userInput.Value
Else
UpdateMessage "Free Typed Input is Selected but Textarea is Blank",2
Exit Sub
End If
Elseif userInputMethod.selectInputMethod(1).checked Then
If Not fileContents.Value = "" Then
strInput = fileContents.Value
Else
UpdateMessage "Selected File is Blank",2
Exit Sub
End If
Else
Exit Sub
End If
'Set Expression
If Not inputExp.Value = "" Then
strExp = inputExp.Value
Else
UpdateMessage "No Expression Entered",2
Exit Sub
End If
'Set Replace
If Not replaceExp.Value = "" Then
strReplace = replaceExp.Value
Else
strReplace = ""
End If
'Save Instruction
If objRecord = True Then
If Not strInstruction = Empty Then
strInstruction = strInstruction & vbCRLF & strUserFunction & "," & strExp & "," & strReplace
Else
strInstruction = strUserFunction & "," & strExp & "," & strReplace
End If
Else
strInstruction = strUserFunction & "," & strExp & "," & strReplace
End If
RunExpression
End Sub
Sub ChooseTextArea
'Display User Input Textarea
'Update GUI
document.all.userInput.style.display="block"
document.all.selectFolder.style.display="none"
document.all.fileContents.style.display = "none"
'Set Choice
objGUIOption = "Type"
End Sub
Sub ChooseFile
'Display File Input
'Update GUI
document.all.userInput.style.display="none"
document.all.selectFolder.style.display="inline"
If Not fileContents.Value = "" Then
document.all.fileContents.style.display = "block"
End If
'Set Choice
objGUIOption = "File"
End Sub
Sub UploadSelectedFile
'Check User Selected File Exists & Load Contained Text
'Reset Error Message
expOutput.innerHTML = ""
'Get User Input & Sanitise
objFilePath = fileInput.Value
objFilePath = Replace(objFilePath,chr(34),"")
'Extract Data from File
If objFSO.FileExists(objFilePath) Then
Set objFileSize = objFSO.GetFile(objFilePath)
If objFileSize.size > 0 Then
Set objFile=objFSO.OpenTextFile(objFilePath,1)
strFileContents=objFile.ReadAll
document.all.fileContents.value=strFileContents
objFile.Close
Else
UpdateMessage "Selected Filed is Blank",2
Exit Sub
End If
Else
UpdateMessage "Input File Does Not Exist",2
Exit Sub
End If
'Make Textarea Visible
document.all.fileContents.style.display = "block"
End Sub
Sub CommitInstruction
'Save Current Instruction to Recipe
'Check that Instruction Exists
If strInstruction = Empty Then
UpdateMessage "Instruction is Blank or Does Not Exist",2
Exit Sub
End If
'Check whether a Recipe Exists
If objFSO.FileExists("C:\Temp\Temp_Recipe.txt") Then
Set objRecipe = objFSO.GetFile("C:\Temp\Temp_Recipe.txt")
'Check the Recipe Contains Instructions
If objRecipe.size > 0 And strUserConfirmedAction = "" Then
'Check How User Wants to Interact with Present Recipe - Overwrite or Amend?
userConfirm = Msgbox("A partial Recipe already exists. Should it be deleted?",35,"How to Proceed?")
'User Decision: Overwrite (Yes - 6) or Amend (No - 7)
If userConfirm = 6 Then
strUserConfirmedAction = "Overwrite"
Elseif userConfirm = 7 Then
'Request Further User Input
userConfirm = Msgbox("Amend the partial Recipe with new Instructions?",33,"How to Proceed?")
If userConfirm = 1 Then
strUserConfirmedAction = "Amend"
Elseif userConfirm = 2 Then
'Cancel Operation & Open Temp Folder
Msgbox "Delete Current Recipe & Try Again",64,"Operation Cancelled"
userConfirm = Empty
UpdateMessage "Commit Cancelled by User",2
Set objShell = CreateObject("shell.application")
objShell.Open("C:\Temp")
Exit Sub
End If
Elseif userConfirm = 2 Then
UpdateMessage "Commit Cancelled by User",2
Exit Sub
End If
Elseif strUserConfirmedAction = "" Then
'If Recipe is Blank, Assume Amending
strUserConfirmedAction = "Amend"
End If
Else
'Set Field so that Recipe will be Created
strUserConfirmedAction = "Amend"
End If
'Write Instruction to Recipe
If strUserConfirmedAction = "Overwrite" Then
'Overwrite Current Recipe & Set to Amend for Further Commits
Set objFile = objFSO.OpenTextFile("C:\Temp\Temp_Recipe.txt",2,1)
objFile.WriteLine strInstruction
objFile.Close
strUserConfirmedAction = "Amend"
Elseif strUserConfirmedAction = "Amend" Then
'Append Current Instruction to Recipe
Set objFile = objFSO.OpenTextFile("C:\Temp\Temp_Recipe.txt",8,1)
objFile.WriteLine strInstruction
objFile.Close
End If
'Clear Instruction
strInstruction = Empty
'Update Input
UpdateInput
UpdateMessage "Instruction Saved and Input Updated",1
End Sub
Sub DeleteRecipe
'User Requests to Delete Current Recipe
'Ensure User Confirmation is Empty
strUserDelete = Empty
'Check that a Recipe Exists
If objFSO.FileExists("C:\Temp\Temp_Recipe.txt") Then
'Request User Confirmation
strUserDelete = Msgbox("Delete Unsaved Recipe Permanently?",17,"Delete File Permanently")
Else
UpdateMessage "No Recipe Found - Cannot Delete",2
Exit Sub
End If
'Delete Recipe
If strUserDelete = 1 Then
objFSO.DeleteFile("C:\Temp\Temp_Recipe.txt")
UpdateMessage "Partial Recipe Deleted",1
Else
UpdateMessage "User Cancelled Delete Operation",2
End If
End Sub
Sub PreviewRecipe
'Preview Current Recipe
'Ensure Values are Empty
strRecipePreview = Empty
'Check that a Recipe Exists
If Not objFSO.FileExists("C:\Temp\Temp_Recipe.txt") Then
UpdateMessage "Recipe Cannot Be Found",2
Exit Sub
Else
Set objRecipe = objFSO.GetFile("C:\Temp\Temp_Recipe.txt")
If Not objRecipe.size > 0 Then
strRecipePreview = "{EMPTY}"
UpdateMessage "Recipe is Currently Blank",1
End If
End If
'Retrieve & Display Recipe
Set objRecipe = objFSO.OpenTextFile("C:\Temp\Temp_Recipe.txt",1)
If strRecipePreview = Empty Then
strRecipePreview = objRecipe.ReadAll
End If
Msgbox strRecipePreview,64,"Recipe Preview:"
End Sub
Sub RecordInstructions
'Continuously Commit Instructions as Each if Run by User
'Reset Button State & User Input
strButtonPressed = False
strUserCommit = Empty
'Start Recording
If objRecord = False And strButtonPressed = False Then
If Not strInstruction = Empty Then
'Request User Input - Delete or Keep Current Instruction?
strUserCommit = Msgbox("Commit Current Instruction?",35,"Instruction Already Exists")
If strUserCommit = 6 Then
CommitInstruction
'If Commit is Cancelled by User then Don't Continue
If Not strInstruction = Empty Then
Exit Sub
End If
Elseif strUserCommit = 7 Then
strInstruction = Empty
Elseif strUserCommit = 2 Then
Exit Sub
End If
End If
objRecord = True
strButtonPressed = True
UpdateMessage "Recording Instructions Initiated",1
runRecord.innerHTML = "Stop (<span class='quickKey'>d</span>)"
End If
'Stop Recording
If objRecord = True And strButtonPressed = False Then
If Not strInstruction = Empty Then
'Request User Input - Delete or Commit Recording?
strUserCommit = Msgbox("Commit Recorded Instructions?",35,"Recording Ended")
If strUserCommit = 6 Then
CommitInstruction
'If Commit is Cancelled by User then Don't Continue
If Not strInstruction = Empty Then
Exit Sub
End If
Elseif strUserCommit = 7 Then
strInstruction = Empty
Elseif strUserCommit = 2 Then
Exit Sub
End If
End If
objRecord = False
strButtonPressed = True
UpdateMessage "Recording Instructions Terminated",1
runRecord.innerHTML = "Recor<span class='quickKey'>d</span>"
End If
End Sub
Sub UpdateInput
'Refresh the Input After a Commit to Allow Continual Editing
'Save Original Text on First Commit
If strOriginalInput = Empty Then
strOriginalInput = strInput
End If
'Update Input
strInput = strOutput
'Update GUI
If objGUIOption = "Type" Then
userInput.innerHTML = strInput
Else
fileContents.innerHTML = strInput
End If
expOutput.innerHTML = ""
End Sub
Sub Test
Msgbox(strOutput)
End Sub
</script>
<style>
body {
margin: 0 20px;
padding: 0;
font-family: "Segoe UI", Geneva, sans-serif;
background: #f3f3f3;
overflow: auto;
}
h1 {
font-size: 15pt;
text-align: center;
margin-bottom: 0;
color: #273754;
}
pre {
line-height: 8px;
font-family: "Courier New", Courier, monospace, sans-serif;
background: #ffffff;
height: 150px;
overflow: auto;
padding: 10px;
}
button {
padding: 10px;
font-size: 16px;
font-weight: 100;
color: #fff;
background: #777d84;
border: 0;
}
button.select {
padding: 5px 10px;
font-size: 12px;
margin: 0 1px;
}
button:hover {
background: #646a70;
}
input[type=text] {
height: 20px;
width: 72%;
}
textarea {
overflow: auto;
}
.error {
color: #e22b2b;
}
.folderInput {
width: 85%;
margin: auto;
}
.folderSelect {
margin:0 20px 0 0;
display: block;
float: left;
width: 100px;
}
.buttonContainer {
margin: auto;
text-align: center;
}
input[type=button].featureButton {
width: 100px;
font-size: 12px;
padding: 5px 10px;
}
span.quickKey {
text-decoration: underline;
}
#logArea {
height: 8px;
}
#retrieveRAW {
margin-top: 20px;
font-weight: bold;
background: #4a8e0b;
}
.right {
float: right;
}
</style>
<body>
<div>
<H1>Test Regular Expression</H1>
<p>
<form id="userInputMethod">
<span class="option">Free Type Input:</span>
<input name="selectInputMethod" type="radio" onClick="ChooseTextArea" checked>
<span class="option">Select File Input:</span>
<input name="selectInputMethod" type="radio" onClick="ChooseFile">
</form>
<textarea name="userInput" rows=10 cols=100></textarea>
<span id="selectFolder"><input type="text" id="fileInput" size=100><button id="runFolder" onClick="UploadSelectedFile">Submit</button></span>
</p>
<p>
<textarea name="fileContents" rows=10 cols=100></textarea>
</p>
</div>
<div>
<p>
Regular Expression to Test:<br>
<input type="text" id="inputExp" size=100>
</p>
<p>
Replace With:<br>
<input type="text" id="replaceExp" size=100>
</p>
</div>
<div>
<button id="runReplace" onClick="GetUserInput('Replace')" accessKey="r"><span class="quickKey">R</span>eplace</button>
<button id="runReplaceAll" onClick="GetUserInput('ReplaceAll')" accessKey="a">Replace <span class="quickKey">A</span>ll</button>
<button id="runFind" onClick="GetUserInput('Find')" accessKey="f"><span class="quickKey">F</span>ind</button>
<span class="right">
<button id="runCommit" onClick="CommitInstruction" accessKey="c"><span class="quickKey">C</span>ommit</button>
<button id="runRecord" onClick="RecordInstructions" accessKey="d">Recor<span class="quickKey">d</span></button>
<button id="runPreview" onClick="PreviewRecipe" accessKey="v">Pre<span class="quickKey">v</span>iew</button>
<button id="runDelete" onClick="DeleteRecipe">Delete</button>
<button id="runTest" onClick="Test" accessKey="t"><span class="quickKey">T</span>est</button>
<button id="runCook" onClick="Test" accessKey="k">Coo<span class="quickKey">k</span></button>
</span><br><br>
</div>
<div>
<pre id="logArea">Ready to Begin...</pre>
</div>
<div>
<pre id="expOutput"></pre>
</div>
</body>
</html>
Pattern Property documentation 关于 $
模式字符太简短了:
$
Matches the end of input.
有关更详细的规范,请阅读 Regular Expression Programming (Scripting) 文章(向下滚动到 Flags 段落)。简而言之:
Flags
In the JScript regular expression
/abc/gim
, theg
specifies the global flag, thei
specifies the ignore case flag, and them
specifies the multiline flag.In VBScript, you can specify these flags by setting the equivalent properties to
True
.…
Multiline
^
matches positions following a\n
or\r
, and$
matches positions before\n
or\r
.
实际上、$
匹配\n
之前的位置(LF)和 在 \r
之前 (CR).
案例说明:
- if 输入字段是 TestCRLFTestCRLF测试
- 正则表达式模式是
$
- 和替换字段为
@
- 正则表达式模式是
- then
Replace All
action results to Test@CR@LF测试@CR@LF测试@
解决方案(通常不正确):
- 使用
\b$
模式(它不会匹配空行的结尾或带有任何尾随白色 space 的行的结尾,包括 space、制表符等) - 在 替换为 字段中使用
\r\n
模式 和 尾随\n
(它不会匹配最后一个不以\r\n
结尾的行,即 CRLF).
出于调试目的,我使用以下代码存根改进了第 147 行的 HTA 代码:
Else
UpdateMessage "Performed Instruction Successfully",1
If strUserFunction <> "Find" Then
MsgBox HexScan(strInput , "strInput" ) _
& HexScan(strReplace, "strReplace") _
& HexScan(strOutput , "strOutput" ), vbOKOnly, "hexadecimals"
End If
End If
End Sub
Function HexScan( Byval strStr, strHead)
HexScan = strHead & Space(1) & CStr( Len(strStr)) & vbNewLine & "hex "
For ii = 1 To Len(strStr)
HexScan = HexScan & Right( "0" & Hex(Asc(Mid(strStr,ii,1))),2) & " "
Next
HexScan = HexScan & vbNewLine
End Function
Sub GetUserInput(strFunction)
'Pull In User Input from Interface