我正在创建一个HTML应用程序,允许用户自由键入textarea
,然后在一个input
框中输入正则表达式模式,并将一个替换字符串转换为第二个input
盒子。当用户按下按钮时,将运行VBScript序列,该序列接受用户输入,创建正则表达式并用字符串替换该模式。我的问题是,当用户选择一行的结尾,即$
的模式时,替换字符串将添加到每一行,而介于每一行。
例如,以下文字:
Test
Test
Test
如果输入@
的替换字符串将输出为:
Test@
@
Test@
@
Test@
如何防止“附加”线出现在输出中?是什么原因导致了他们?
申请代码如下:
<!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>
答案 0 :(得分:2)
Pattern Property documentation关于$
模式字符过于简短:
$
匹配输入的结尾。
有关更详细的说明,请阅读Regular Expression Programming (Scripting)文章(向下滚动到 Flags 段落)。简而言之:
标志
在JScript正则表达式
/abc/gim
中,g
指定了 全局标志,i
指定忽略大小写标志,m
指定多行标志。在VBScript中,您可以通过设置等效项来指定这些标志 属性为
True
。...
多
- 后的排名
^
匹配\n
或\r
和$
匹配\n
或\r
之前的位置。
实际,$
匹配\n
之前的\r
( LF )和之前的位置( CR )。
案例说明:
$
@
Replace All
操作结果为测试@ CR @ LF 测试@ CR @ LF 测试@ 强> 解决方案(通常不是):
\b$
模式(它不会匹配空行的结尾或行尾与任何尾随空格,包括空格,制表符等。)\r\n
模式和结尾\n
(它不会与不以{{1}结尾的最后一行匹配} CR LF )。出于调试目的,我使用以下代码存根改进了#147行的HTA代码:
\r\n