Structure replacement possible complex RegexReplace solution? - regex

I need to run a VBScript that changes the structure of a CSV file. To keep it simple I'm only using 3 data fields but there is a lot more. In a production environment I will have a CSV file with hundreds of lines.
The problem is everything is in double quotes. The end result can sometimes be no quotes or single quotes or sometimes a mix of all three.
I have absolutely no idea how I should approach this and was looking for some guidance. This looks like a job for RegexReplace but because it's mixed I'm not sure how to start this. After the file has been modified I have to right over top of the original file.
CSV Example:
"apple";"12";"xyz"
"somereallylongword";"7687";"theredfox"
Pattern
"%1";%2;'%3'
Desired Result
"apple";12;'xyz'
"somereallylongword";7687;'theredfox'
What I'm trying to achieve is to be able to make a new pattern type.  In my example:
"%1" - I keep the original double quotes.
%2 - Remove the double quotes.
'%3' - Replace the double quotes with single quotes.
Any insight would be greatly appreciated.

You can read the CSV file using ADODB:
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H1
Dim objConnection
Dim objRecordset
Dim sCSVFolder
Dim sCSVFile
Dim sValue
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
sCSVFolder = "C:\CSV_Folder\"
sCSVFile = "your_csv_file.csv"
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & sCSVFolder & ";" & _
"Extended Properties=""text;HDR=YES;FMT=Delimited"""
objRecordset.Open "SELECT * FROM " & sCSVFile, _
objConnection, adOpenStatic, adLockOptimistic, adCmdText
Do Until objRecordset.EOF
' Modify and write fields to new text file here
sValue = objRecordset.Fields.Item("FieldName")
objRecordset.MoveNext
Loop
This way you let ADO handle reading the data and removing the double-quotes and you can manipulate the data easily as a Recordset.

Just give a try for this code by replacing the path of your CSV file and tell me how it works on your side ?
Option Explicit
Dim Data
Call ForceCScriptExecution()
Data = ReadFile("C:\Test\Test.csv")
wscript.echo "Before Replacing"
wscript.echo String(50,"-")
wscript.echo Data
wscript.echo String(50,"-")
wscript.echo "After Replacing"
wscript.echo String(50,"-")
wscript.echo Search_Replace(Data)
wscript.echo String(50,"-")
wscript.sleep 20000
'-----------------------------------------------
Function Search_Replace(Data)
Dim oRegExp,strPattern1,strPattern2
Dim strReplace1,strReplace2,strResult1,strResult2
strPattern1 = ";(\x22)(\S+\w+)(\x22);"
strReplace1 = ";$2;"
strPattern2 = "[;]\x22([^\x22]+)\x22"
strReplace2 = ";'$1'"
Set oRegExp = New RegExp
oRegExp.Global = True
oRegExp.IgnoreCase = True
oRegExp.Pattern = strPattern1
strResult1 = oRegExp.Replace(Data,strReplace1)
oRegExp.Pattern = strPattern2
strResult2 = oRegExp.Replace(strResult1,strReplace2)
Search_Replace = strResult2
End Function
'-----------------------------------------------
Function ReadFile(path)
Const ForReading = 1
Dim objFSO,objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(path,ForReading)
ReadFile = objFile.ReadAll
objFile.Close
End Function
'----------------------------------------------
Sub ForceCScriptExecution()
Dim Arg, Str, cmd, Title
Title = "Search and Replace using RegExp by Hackoo 2019"
cmd = "CMD /C Title " & Title &" & color 0A & Mode 80,30 & "
If Not LCase( Right( WScript.FullName, 12 ) ) = "\cscript.exe" Then
For Each Arg In WScript.Arguments
If InStr( Arg, " " ) Then Arg = """" & Arg & """"
Str = Str & " " & Arg
Next
CreateObject( "WScript.Shell" ).Run _
cmd & "cscript //nologo """ & _
WScript.ScriptFullName & _
""" " & Str
WScript.Quit
End If
End Sub
'-----------------------------------------------
Edit : Batch Script Code
You can do it easily with a batch script without using Regex :
#echo off
Title Edit CSV File
Set "Input_CSV_File=C:\Test\Test.csv"
Set "OutPut_CSV_File=C:\Test\OutPut_Test.csv"
If Exist "%OutPut_CSV_File%" Del "%OutPut_CSV_File%"
#for /f "tokens=1,2,3 delims=;" %%a in ('Type "%Input_CSV_File%"') Do (
echo "%%~a";%%~b;'%%~c'
echo "%%~a";%%~b;'%%~c'>>"%OutPut_CSV_File%"
)
TimeOut /T 5 /NoBreak>nul
If Exist "%OutPut_CSV_File%" Notepad "%OutPut_CSV_File%" & Exit

Related

Change Text in Textfile with Search & Replace + Regex | Batchfile

I need to write a .bat/.cmd/.vbs file that changes the text of a text file and I also need regex terms.
I have the following text file as .txt.
"Bild/Print/59/00-Einstiegsbild-neu_59115.jpg" -resize 227.05x227.05%% -rotate -0 -shear 0x0 -crop 2011x1051+104+328 "web\00-Einstiegsbild-neu_59115.jpg"
"Bild/Print/59/01-Zwischenbild-neu_59150.jpg" -resize 100.39x100.39%% -rotate -0 -shear 0x0 -crop 2012x988+0+82 "web\01-Zwischenbild-neu_59150.jpg"
Now I want to do the following regex search and replace:
(1. Replace)
Search: "
Replace: (nothing)
(2. Replace)
Search: .+(?=web)
Replace: (nothing)
Now the text should be:
web\00-Einstiegsbild-neu_59115.jpg
web\01-Zwischenbild-neu_59150.jpg
(3. Replace)
Search: web\\
Replace: E:\K4_XML_Export\tpx_K4toWP_ImageMagick\web\
which should result in:
E:\K4_XML_Export\tpx_K4toWP_ImageMagick\web\00-Einstiegsbild-neu_59115.jpg
E:\K4_XML_Export\tpx_K4toWP_ImageMagick\web\01-Zwischenbild-neu_59150.jpg
Since I have absolutely no idea about batch files I hope you can help me further or share certain approaches or considerations.
Thank you in advance for the feedback and best regards
Noel
What I already tested – I know how to change text like red to blue with:
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "E:\imglist_2.txt"
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If InStr(strLine,"red")> 0 Then
strLine = Replace(strLine,"red","blue")
End If
WScript.Echo strLine
Loop
cscript /nologo E:\test.vbs > newfile
ren newfile file.txt
I hope this helps... Regular expression can skip a few steps ahead and just grab the string (web...) without needing the redundant steps. Resulting in the desired pattern output.
Please note you'll need to update this version back to your file strFile = "E:\imglist_2.txt"
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim objFS, objFile, PrimaryPath, strFile
PrimaryPath="E:\K4_XML_Export\tpx_K4toWP_ImageMagick"
strFile = "imagelist.txt"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.OpenTextFile(strFile, ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If InStr(strLine,"web")> 0 Then ImagePath = PrimaryPath & "\" & GetWebImg(strLine)
WScript.Echo ImagePath
Loop
Function GetWebImg(str)
Set RE = CreateObject("VBScript.RegExp")
RE.Global = True
RE.Pattern = "(web[^""]*)"
Set matches = RE.Execute(str)
If matches.count > 0 Then
GetWebImg=matches(0)
End If
End Function

Regex Adding Unnecessary Spaces During Replace

I'm currently having difficulty with a VBScript I'm writing that contains several read and replaces from a text file. The expression I'm using finds the expression and replaces it, but adds three tab spaces afterwords, making the original line below it mess up the formatting. Here's a picture of what I'm talking about:
Here's a pastebin of the before and after, rather than an image:
https://pastebin.com/Uw3H59QK
Here's my RegExp code:
Set fso = CreateObject("Scripting.FileSystemObject")
Dim strPath
strPath = SelectFolder( "" )
If strPath = vbNull Then
WScript.Echo "Script Cancelled - No files have been modified" 'if the user cancels the open folder dialog
Else
WScript.Echo "Selected Folder: """ & strPath & """" 'prompt that tells you the folder you selected
End If
Function SelectFolder( myStartFolder )
Dim objFolder, objItem, objShell
Dim objFolderItems
On Error Resume Next
SelectFolder = vbNull
Set objShell = CreateObject( "Shell.Application" )
Set objFolder = objShell.BrowseForFolder( 0, "Please select the .dat file location folder", 0, myStartFolder)
set objFolderItems = objFolder.Items
If IsObject( objFolder ) Then SelectFolder = objFolder.Self.Path
Set objFolder = Nothing
Set objShell = Nothing
On Error Goto 0
End Function
Set re = New RegExp 'Replacing Position Lines
re.Pattern = "Pos = \((.*)\)"
re.Global = True
re.IgnoreCase = True
For Each f in fso.GetFolder(strPath).Files
If LCase(fso.GetExtensionName(f.Name)) = "txt" Then
text = f.OpenAsTextStream.ReadAll 'reading the text file
f.OpenAsTextStream(2).Write re.Replace(text, """Position"" : mathutils.Vector(($1)),")
count = count + 1
End If
Next
Set reAngles = New RegExp 'Replacing Angles
reAngles.Pattern = "Angles = \((.*)\)"
reAngles.Global = True
reAngles.IgnoreCase = True
For Each f in fso.GetFolder(strPath).files
If LCase(fso.GetExtensionName(f.Name)) = "txt" Then
text = f.OpenAsTextStream.ReadAll
f.OpenAsTextStream(2).Write reAngles.Replace(text, """Angles"" : mathutils.Vector(($1)),")
End If
Next
Set reNames = New RegExp 'Replacing Names
reNames.Pattern = "Name = (.*)"
reNames.Global = True
'reNames.Multiline = True
reNames.IgnoreCase = True
For Each f in fso.GetFolder(strPath).files
If LCase(fso.GetExtensionName(f.Name)) = "txt" Then
text = f.OpenAsTextStream.ReadAll
f.OpenAsTextStream(2).Write reNames.Replace(text, """Name"" : ""$1"",")
End If
Next
My best guess is that the wildcard is grabbing more info than needed...but I'm unsure how to fix that. I used a lot of these expressions in Notepad++ so I was hoping to translate them to a VBS easily!

Extract all lines of a file between 2 delimiters without them in VBScript Regex

I try to Extract all lines of a file between 2 strings in another file and without these delimiters.
Example:
[General]
Description=Description
[extractSection]
First Line extracted. It is not an ini section
Last Line extracted
[OthersSection]
blablabla
It seems to work with this script. One of my first vbs.
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "E:\Temp\Test.txt"
strTemp = "E:\Temp\Temp.txt"
If objFS.FileExists(strTemp) Then objFS.DeleteFile(strTemp)
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If isReading = True Then
If instr(strline,"[") Then
Set objOutFile = objFS.CreateTextFile(strTemp, True)
objOutFile.Write(strLine1)
objOutFile.Close
Exit Do
Else
strline1 = strline1 & strline & vbNewLine
End If
Else
If instr(LCase(strline),"[extractsection]") Then
isReading = True
End If
End If
Loop
objFile.Close
But it seems not very optimized, I have files up to 8Mb.
I would like to try the same thing using Regex. I never used, I have to learn.
I have this as beginning: \[extractsection\]([\s\S]*?)\[[\s\S]
But I would like without the delimiters.
Thank you Wiktor. It seems it is OK with (?<=\[extractSection\]\n)(.*(?:\n(?!\[).*)*) Just let me know what is best (Ram | speed) vs my ReadLine script on top, please
You can give a try for this vbscript without a Regex :
Option Explicit
Dim strFile,strTemp,Full_String,First_Delimiter,Second_Delimiter,Extracted_Data
strFile = "E:\Temp\Test.txt"
strTemp = "E:\Temp\Temp.txt"
Full_String = ReadFileText(strFile)
First_Delimiter = "[extractSection]"
Second_Delimiter = "[OthersSection]"
Extracted_Data = String_Between(Full_String,First_Delimiter,Second_Delimiter)
wscript.echo Extracted_Data
Write2File Extracted_Data,strTemp
'************************************************************************************************
Function String_Between(ByVal Full_String, ByVal First_Delimiter, ByVal Second_Delimiter)
Dim Pos,Pos2
Pos = InStr(Full_String, First_Delimiter)
Pos2 = InStr(Full_String, Second_Delimiter)
If Pos = 0 Or Pos2 = 0 Then
String_Between = "Missing Delimiter"
Exit Function
End If
String_Between = Mid(Full_String, Pos + Len(First_Delimiter), Pos2 - (Pos + Len(First_Delimiter)))
End Function
'***********************************************************************************************
Function ReadFileText(sFile)
Dim objFSO,oTS,sText
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FileExists(sFile) Then
MsgBox "CRITICAL ERROR " & VbCrLF & "The File "& DblQuote(sFile) &_
" dosen't exists !",VbCritical,"CRITICAL ERROR"
Wscript.Quit
Else
Set oTS = objFSO.OpenTextFile(sFile)
sText = oTS.ReadAll
oTS.close
set oTS = nothing
Set objFSO = nothing
ReadFileText = sText
End if
End Function
'*********************************************************************************************
Sub Write2File(strText,OutputFile)
Dim fs,ts
Const ForWriting = 2
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.OpenTextFile(OutputFile,ForWriting,True)
ts.WriteLine strText
ts.Close
End Sub
'*********************************************************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'**********************************************************************************************
And this one with RegEx
Option Explicit
Dim strFile,strTemp,Full_String,First_Delimiter,Second_Delimiter,Extracted_Data
strFile = "E:\Temp\Test.txt"
strTemp = "E:\Temp\Temp.txt"
Full_String = ReadFileText(strFile)
First_Delimiter = "[extractSection]"
Second_Delimiter = "[OthersSection]"
Extracted_Data = ExtractData(Full_String,First_Delimiter,Second_Delimiter)
wscript.echo Extracted_Data
Write2File Extracted_Data,strTemp
'***********************************************************************************************
Function ExtractData(Full_String,Start_Delim,End_Delim)
Dim fso,f,r,Matches,Contents,Data
Start_Delim = Replace(Start_Delim,"[","\[")
Start_Delim = Replace(Start_Delim,"]","\]")
End_Delim = Replace(End_Delim,"[","\[")
End_Delim = Replace(End_Delim,"]","\]")
Set r=new regexp
r.pattern = "(?:^|(?:\r\n))(:?"& Start_Delim &"\r\n)([\s\S]*?)(?:\r\n)(?:"& End_Delim &")"
Set Matches = r.Execute(Full_String)
If Matches.Count > 0 Then Data = Matches(0).SubMatches(1)
ExtractData = Data
End Function
'***********************************************************************************************
Function ReadFileText(sFile)
Dim objFSO,oTS,sText
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FileExists(sFile) Then
MsgBox "CRITICAL ERROR " & VbCrLF & "The File "& DblQuote(sFile) &_
" dosen't exists !",VbCritical,"CRITICAL ERROR"
Wscript.Quit
Else
Set oTS = objFSO.OpenTextFile(sFile)
sText = oTS.ReadAll
oTS.close
set oTS = nothing
Set objFSO = nothing
ReadFileText = sText
End if
End Function
'*********************************************************************************************
Sub Write2File(strText,OutputFile)
Dim fs,ts
Const ForWriting = 2
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.OpenTextFile(OutputFile,ForWriting,True)
ts.WriteLine strText
ts.Close
End Sub
'*********************************************************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'**********************************************************************************************

Find and Replace string in a .txt file with VBscript

I am trying to figure out how to use vbscript to:
1 - open a .csv file as a .txt file
2 - search for a certain string of text that is located randomly throughout the text
3 - replace that string with a different string.
I have found an article that helped me learn how to replace an entire line in a .txt document, but so far have had no luck finding anything about replacing just certain characters within the line.
Thanks!
Here is the code I am using currently:
Const ForReading = 1
Const ForWriting = 2
'Setting up our objects and focusing on the text file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Users\Documents\Script Practice\TextFiles-2-4-15-Folder\ReadandWrite\Textlook.txt", ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If strLine = "Myer" Then
strLine = "Mike"
End If
strContents = strContents & strLine & vbCrLf
Loop
objFile.Close
Set objFile = objFSO.OpenTextFile("C:\Users\Documents\Script Practice\TextFiles-2-4-15-Folder\ReadandWrite\Textlook.txt", ForWriting)
objFile.Write(strContents)
objFile.Close
The text file it references says:
Ken Myer
Fabrikam
Pilar Ackerman
Wingtip Toys
Jeff Hay
Fabrikam
Ellen Adams
Northwind Traders
Myer
(End of text file). So essentially, I have gotten the code to successfully change the "Myer" that is on its own line to "Mike". What I am having a hard time with is changing the "Myer" in the first line to "Mike". Hopefully this helps clarify things a bit...I'm extremely new at this so not sure of the language I should be using to describe the problem.
Use Replace on the file's content obtained by .ReadAll() and .Write the result back. In code:
Option Explicit
Dim goFS : Set goFS = Createobject("Scripting.FileSystemObject")
Dim goWAU : Set goWAU = WScript.Arguments.Unnamed
WScript.Quit main()
Function main()
main = 1 ' assume error
If 3 = goWAU.Count Then
If goFS.FileExists(goWAU(0)) Then
Dim s : s = goFS.OpenTextFile(goWAU(0)).ReadAll()
If 0 < Instr(s, goWAU(1)) Then
goFS.CreateTextFile(goWAU(0)).Write Replace(s, goWAU(1), goWAU(2))
WScript.Echo "done"
main = 0
Else
WScript.Echo goWAU(1), "not found"
End If
Else
WScript.Echo goWAU(0), "does not exist"
End If
Else
WScript.Echo "need 3 args: fspec, find, replacement"
End If
End Function
output:
copy con 28350055.csv
1,2,3
4,5,6
^Z
cscript 28350055.vbs 28350055.csv 5 4711
done
type 28350055.csv
1,2,3
4,4711,6
cscript 28350055.vbs 28350055.csv 5 4711
5 not found
cscript 28350055.vbs 28350055.cs 5 4711
28350055.cs does not exist
Use that demo to determine what is needed to solve your real world problem.
I'm extremly new too, so i didnt get what the other answer do in the code, but i figured out in the last answer about "Replace" and use in your code for do what you need, and the result is this:
Const ForReading = 1
Const ForWriting = 2
'Setting up our objects and focusing on the text file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Users\Documents\Script Practice\TextFiles-2-4-15-Folder\ReadandWrite\Textlook.txt", ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
strLine = Replace(strLine,"Myer","Mike")
' If strLine = "Myer" Then
' strLine = "Mike"
' End If
strContents = strContents & strLine & vbCrLf
Loop
objFile.Close
Set objFile = objFSO.OpenTextFile("F:\BIBLIOTECAS\Archivos\TEST.txt", ForWriting)
objFile.Write(strContents)
objFile.Close

classic asp ignore comma within speech marks CSV

I have a CSV File that looks like this
1,HELLO,ENGLISH
2,HELLO1,ENGLISH
3,HELLO2,ENGLISH
4,HELLO3,ENGLISH
5,HELLO4,ENGLISH
6,HELLO5,ENGLISH
7,HELLO6,ENGLISH
8,"HELLO7, HELLO7 ...",ENGLISH
9,HELLO7,ENGLISH
10,HELLO7,ENGLISH
I want to step loop through the lines and write to a table using split classic asp function by comma. When Speech marks are present to ignore the comma within those speech marks and take the string.
<%
dim csv_to_import,counter,line,fso,objFile
csv_to_import="uploads/testLang.csv"
set fso = createobject("scripting.filesystemobject")
set objFile = fso.opentextfile(server.mappath(csv_to_import))
str_imported_data="<table cellpadding='3' cellspacing='1' border='1'>"
Do Until objFile.AtEndOfStream
line = split(objFile.ReadLine,",")
str_imported_data=str_imported_data&"<tr>"
total_records=ubound(line)
for i=0 to total_records
if i>0 then
str_imported_data=str_imported_data&"<td>"&line(i)&"</td>"
else
str_imported_data=str_imported_data&"<th>"&line(i)&"</th>"
end if
next
str_imported_data=str_imported_data&"</tr>" & chr(13)
Loop
str_imported_data=str_imported_data&"<caption>Total Number of Records: "&total_records&"</caption></table>"
objFile.Close
response.Write str_imported_data
%>
Don't write your own CSV parser.
You start with "splitting it on the , is the way to go, now I am finished". Then someone uses a comma in your data and the string with the comma is surrounded by double quotes. You are a smart man, so you count the amount of double quotes and if they are odd, you know you have to escape the comma and if they are even, you don't have to. And then you get a CSV file containing escaped double quote characters...
But wait! There is a solution. Use a Database Connection to your file!
It will be something like this, but you'll have to adapt it to your own situation:
On Error Resume Next
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H0001
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
strPathtoTextFile = server.mappath("uploads/")
strFileName = "testLang.csv"
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strPathtoTextFile & ";" & _
"Extended Properties=""text;HDR=NO;FMT=CSVDelimited"""
objRecordset.Open "SELECT * FROM " & strFileName, _
objConnection, adOpenStatic, adLockOptimistic, adCmdText
Do Until objRecordset.EOF
Wscript.Echo "Number: " & objRecordset.Fields.Item(1)
Wscript.Echo "Greeting: " & objRecordset.Fields.Item(2)
Wscript.Echo "Language: " & objRecordset.Fields.Item(3)
objRecordset.MoveNext
Loop