Find/Replace a 'block' of text in a text file?
I have a program I am working on to make modifying my game CFG files for one of my racing games. What I am trying to do is search the opened CFG file for a certain 'block' of text, and replace it with another 'block' of text, without disturbing the rest of the file's structure. I am still relatively new to .NET, so bear with me if I don't word things clearly!
This is a section of the CFG file (The bold area is the 'block' I need to find and replace):
Code:
# Vehicle importer wizard generated vehicle configuration file #
center -0.005 0.670 0.019
material 0x00000000 0x0005000B 0x0005000B
compound
compound
chassis
body 0.0 0.0 0.0 0.0 0.0 0.0 0.001 box 0.001 0.001 0.001
noclick
bone
body 0.001 -0.227 -1.833 0.000 0.000 0.000 10.000 cars\racers\Axis_V3\meshes\_phys_chassis_F.scx ;0x0000000C
# FL wheel #
type 10.000 sphere 0.44
spring 0.290 0.100 0.050
wheel -0.785 -0.544 -1.305 0.000 0.000 0.000 1.000 1.000 1.000 0.000
wheelbones
slot 0.000 0.000 0.000 0.000 0.000 0.000 101 ; FL wheel
attach 0x00040100 1 ; 14
attach 0x00040101 1 ; 15
attach 0x00040102 1 ; 16
attach 0x00040103 1 ; 17
attach 0x00040104 1 ; 18
attach 0x00040105 1 ; 19
attach 0x00040106 1 ; 20
attach 0x00040107 1 ; 21
slottype 101
slotdmgmode 0x00000005
slot 0.000 0.000 0.000 0.000 0.000 0.000 201 ; FL suspension arm
slottype 301
slotdmgmode 0x00000006
Is there any way to find that highlighted section, and replace it with a similar section?
Re: Find/Replace a 'block' of text in a text file?
I used a loop.. didn't disturb my data..........
Code:
Dim techList As ArrayList = New ArrayList
Dim sr As IO.StreamReader = New IO.StreamReader(myPath() & "activeTechs.txt")
Dim tech As String
Dim techPos, counter As Integer
counter = 0
While Not sr.EndOfStream
tech = sr.ReadLine()
techList.Add(tech)
If tech = val1 Then techPos = counter
counter += 1
End While
sr.Close()
techList.RemoveAt(techPos)
techList.Insert(techPos, val1)
Dim newData As IO.StreamWriter = New IO.StreamWriter(myPath() & "activeTechs.txt", False)
newData.Write("")
newData.Close()
Dim sw As IO.StreamWriter = New IO.StreamWriter(myPath() & "activeTechs.txt", True)
For aTech As Integer = 0 To (techList.Count - 1)
sw.WriteLine(techList(aTech))
Next
sw.Close()
sorry duke.. I just copied and pasted from something I did.. didnt change it cuz im too tipsy to think....
Re: Find/Replace a 'block' of text in a text file?
Thanks for responding - I just have one question: What should 'val1' be?
Re: Find/Replace a 'block' of text in a text file?
thats the new data.. this is part of a function & val1 was passed as a parameter..
Re: Find/Replace a 'block' of text in a text file?
whow are you inserting the new data? where is it coming from? (and val1 was passed to a procedure not a funtion... errr)
Re: Find/Replace a 'block' of text in a text file?
I have the CFG file text loaded into TextBox1, the block to search for is in TextBox2, and the replacement block is in TextBox3 - Like I said, I'm not too familiar with .NET :-P
Re: Find/Replace a 'block' of text in a text file?
dont really need textbox1...
now if the replacement is in textbox 3, im assuming this is a multiline textbox..
personally i would change textbox2 and textbox3 to a datagrid view.
one column would have the term to search for and another column would have the term to replace it with.
That way i think its easier to control the line breaks and have a 1 to 1 with which to replace with...
then a button to perform the operation. The datagridview will auto add a new row whenever data is entered.
2 Attachment(s)
Re: Find/Replace a 'block' of text in a text file?
ok take a looksy.. hope it works for u...
I'm sure it needs some tweeking, but it works...
pardon the solution name.. its a reminder for me to delete or re-use... its in visual studio 2010
Attachment 90573
Code:
Private Sub OpenFile(sender As System.Object, e As System.EventArgs) Handles OpenFile_But.Click
Dim fileselector As OpenFileDialog = Me.OpenFileDialog1
Dim filePath As String
Dim fileReader As IO.StreamReader
Dim filedata As ArrayList = New ArrayList
fileselector.ShowDialog()
filePath = fileselector.FileName
fileselector.Dispose()
Me.FileSelected_Label.Text = filePath
Me.FileSelected_Label.Refresh()
fileReader = New IO.StreamReader(filePath)
filedata.Clear()
While Not fileReader.EndOfStream
filedata.Add(fileReader.ReadLine)
End While
fileReader.Close()
showData(filedata)
End Sub
Private Sub showData(ByVal dataArray As ArrayList)
For Each dataItem As String In dataArray
DataViewer_ListBox.Items.Add(dataItem)
Next
End Sub
Private Sub TransferForEditing(sender As System.Object, e As System.EventArgs) Handles EditSelected_But.Click
Dim rowNum As Integer = 0
If DataViewer_ListBox.SelectedItems.Count < 1 Then
MsgBox("You must select data to edit!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "Error: Data Empty")
Exit Sub
End If
DataEditor_DGridView.Rows.Clear()
For Each selectedData As String In DataViewer_ListBox.SelectedItems
DataEditor_DGridView.Rows.Add()
DataEditor_DGridView.Rows(rowNum).Cells("oldData").Value = selectedData
rowNum += 1
Next
End Sub
Private Sub DoFileEdit(sender As System.Object, e As System.EventArgs) Handles EditData_But.Click
Dim dataPath As String = FileSelected_Label.Text
Dim newData As New ArrayList
newData = ReadFileData(dataPath)
WriteFileData(dataPath, newData)
MsgBox("File was edited successfully", MsgBoxStyle.Information + MsgBoxStyle.OkOnly)
End Sub
Private Function ReadFileData(ByVal dataPath As String) As ArrayList
Dim adataReader As IO.StreamReader = New IO.StreamReader(dataPath, True)
Dim tempData As New ArrayList
Dim dataLine As String
While Not adataReader.EndOfStream
dataLine = adataReader.ReadLine()
tempData.Add(dataLine)
End While
adataReader.Close()
Return tempData
End Function
Private Sub WriteFileData(ByVal dataPath As String, ByVal dataArray As ArrayList)
Dim dataWriter As IO.StreamWriter = New IO.StreamWriter(dataPath, False)
For Each rowToEdit As DataGridViewRow In DataEditor_DGridView.Rows
For tempItem As Integer = 0 To (dataArray.Count - 1) Step 1
If rowToEdit.Cells("oldData").Value = dataArray(tempItem) Then
dataArray(tempItem) = rowToEdit.Cells("newData").Value
End If
Next
Next
For newItem As Integer = 0 To (dataArray.Count - 1) Step 1
dataWriter.WriteLine(dataArray(newItem))
Next
dataWriter.Close()
End Sub
Re: Find/Replace a 'block' of text in a text file?
grrr... I shoulda added a refresh to the listbox to reflect the file data after its been edited....
Maybe break the openfile procedure into 2... one for choosing the file.. one to grab the file data and display it with path as parameter... then i coulda called it again to refresh the box...
EDIT:
uh.. I did.. lol..
Re: Find/Replace a 'block' of text in a text file?
Thank you for helping me out with this - I've never used the grid before, so this is something new LOL
I ran your program, opened my 'test' CFG file, selected the block of text to change, which did put the block in the data boxes, but when I try to replace the string, I get a 'Nothing to edit' msgbox - I entered the new string in, and 'Confirmed edit', and that's when the msgbox pops up o_O
Ignore the post above - I ran the wrong 'trash' :-P
Now to see if I can get it to work for my purpose!
Re: Find/Replace a 'block' of text in a text file?
thats funny because i did the exact same thing when i went to show it to my friend.. lol>> just noticed on ini files it doesnt get permission even when run under admin
Re: Find/Replace a 'block' of text in a text file?
NOW the problem I'm having is that some of the blocks that are replacing the existing ones are 2-3 lines LONGER, so I can't replace what doesn't exist o_O
Is there a way to add the ones that don't have anything to replace to new lines UNDER the replaced blocks?
Re: Find/Replace a 'block' of text in a text file?
hmmm..... i used it for a little while and didnt run into anything like that.. I think I will add a feature to delete lines, but what you describe sounds like a bug.. I want to look into that...
If theres any details you can provide as to when this happens let me know..
Re: Find/Replace a 'block' of text in a text file?
I can help you on this. But I need to know one thing before I provide you with any sample code. Is this as big as the file is going to get? Or is this only a portion of a larger file that you have? (For the sample text you provided in the first post?)
1 Attachment(s)
Re: Find/Replace a 'block' of text in a text file?
Ok i didnt run into that issue, but i see wut may have caused it... I never jumped out of the loop after i found what i wanted to replace..
Changes:
Can now delete a line
Exit loop after choosing to edit or delete a line
The data is now copied to the edit box for easier editing
Data is selected for edit/delete based on line number not value
Split the open file sub-procedure into two. (one to open file, one to write file to screen)
After file is edited it updates on screen (thanks to splitting openfile sub)
Back up is created whenever file is opened for editing
Can create manual backup
Few cosmetic changed
Few other minor stuff...
if you just want the stand alone exe:
http://www.4shared.com/zip/t6tQHqOU/SimpleFileEdit.html
or the solution is in attachment....
Re: Find/Replace a 'block' of text in a text file?
Quote:
Originally Posted by
AceInfinity
I can help you on this. But I need to know one thing before I provide you with any sample code. Is this as big as the file is going to get? Or is this only a portion of a larger file that you have? (For the sample text you provided in the first post?)
The file is slightly larger - It is a CFG file that holds all the data to 'create' a vehicle in one of my games ...
Quote:
Originally Posted by
elielCT
Ok i didnt run into that issue, but i see wut may have caused it... I never jumped out of the loop after i found what i wanted to replace..
Changes:
Can now delete a line
Exit loop after choosing to edit or delete a line
The data is now copied to the edit box for easier editing
Data is selected for edit/delete based on line number not value
Split the open file sub-procedure into two. (one to open file, one to write file to screen)
After file is edited it updates on screen (thanks to splitting openfile sub)
Back up is created whenever file is opened for editing
Can create manual backup
Few cosmetic changed
Few other minor stuff...
or the solution is in attachment....
I will test it out in a little while - I just got up to find some d**k sliced the valve stem on my new freaking tire last night :-s
Re: Find/Replace a 'block' of text in a text file?
smh.. at least it was just a valve stem... $1 per stem & dont even have to balance if u know wut ur doing...
Re: Find/Replace a 'block' of text in a text file?
Quote:
Originally Posted by
relentlesstech
The file is slightly larger - It is a CFG file that holds all the data to 'create' a vehicle in one of my games ...
That will make things a bit easier then if we can use the System.IO.File methods.
I came up with this:
vbnet Code:
Dim fileText As String = File.ReadAllText("F:\file.txt")
Dim attchRegion As String = String.Join(Environment.NewLine, _
Regex.Matches(fileText, "attach\t\t0x\d{8}\b 1 ; \d{2}\b") _
.Cast(Of Match)().Select(Function(m) m.Value))
fileText = fileText.Replace(attchRegion, "NEW REPLACEMENT VALUE")
TextBox1.Text = fileText
And from the input file I had:
Quote:
# Vehicle importer wizard generated vehicle configuration file #
center -0.005 0.670 0.019
material 0x00000000 0x0005000B 0x0005000B
compound
compound
chassis
body 0.0 0.0 0.0 0.0 0.0 0.0 0.001 box 0.001 0.001 0.001
noclick
bone
body 0.001 -0.227 -1.833 0.000 0.000 0.000 10.000 cars\racers\Axis_V3\meshes\_phys_chassis_F.scx ;0x0000000C
# FL wheel #
type 10.000 sphere 0.44
spring 0.290 0.100 0.050
wheel -0.785 -0.544 -1.305 0.000 0.000 0.000 1.000 1.000 1.000 0.000
wheelbones
slot 0.000 0.000 0.000 0.000 0.000 0.000 101 ; FL wheel
attach 0x00040100 1 ; 14
attach 0x00040101 1 ; 15
attach 0x00040102 1 ; 16
attach 0x00040103 1 ; 17
attach 0x00040104 1 ; 18
attach 0x00040105 1 ; 19
attach 0x00040106 1 ; 20
attach 0x00040107 1 ; 21
slottype 101
slotdmgmode 0x00000005
slot 0.000 0.000 0.000 0.000 0.000 0.000 201 ; FL suspension arm
slottype 301
slotdmgmode 0x00000006
It gave me:
Quote:
# Vehicle importer wizard generated vehicle configuration file #
center -0.005 0.670 0.019
material 0x00000000 0x0005000B 0x0005000B
compound
compound
chassis
body 0.0 0.0 0.0 0.0 0.0 0.0 0.001 box 0.001 0.001 0.001
noclick
bone
body 0.001 -0.227 -1.833 0.000 0.000 0.000 10.000 cars\racers\Axis_V3\meshes\_phys_chassis_F.scx ;0x0000000C
# FL wheel #
type 10.000 sphere 0.44
spring 0.290 0.100 0.050
wheel -0.785 -0.544 -1.305 0.000 0.000 0.000 1.000 1.000 1.000 0.000
wheelbones
slot 0.000 0.000 0.000 0.000 0.000 0.000 101 ; FL wheel
NEW REPLACEMENT VALUE
slottype 101
slotdmgmode 0x00000005
slot 0.000 0.000 0.000 0.000 0.000 0.000 201 ; FL suspension arm
slottype 301
slotdmgmode 0x00000006
I'm assuming the replacement value will be another bunch of "attach 0x00040104 1 ; 18" similar values. So as long as you String.Join() these values with a newline, then when it comes time to use my Regex LINQ, then it will match every one of those lines in the textfile of those attach lines.
Note: For my regex, I assumed that the 1 in each of those lines will never be a different number, if it is, I can just change my regex around a bit.
If it's only going to always be one digit:
Code:
attach\t\t0x\d{8}\b [0-9] ; \d{2}\b
Re: Find/Replace a 'block' of text in a text file?
Okay, now I have a new problem - The gridview editor part is perfect, with a little modification with the other coding, but here is the issue now:
I have a frmMAIN that is my 'startup' form, which users select between two editing methods - One is supposed to open the 'gridview' form, and the other opens the 'textbox' form (I have the two different 'readers' for each) - First off, I got the messagebox.result to finally work correctly, but now when it loads the assigned form, the frmMain is always visible, no matter what (And if I Dispose, it ends the program) - That is problem #1 - Problem #2 is with the textbox editor, the CFG file loads fine, but I cannot save due to the fact that it is already in use 'somewhere', although it's closed in every instance - I just don't get it!
This is what I have for my frmMain coding - Very simple, but does not go away when other forms are loaded! :-(
Code:
Public Class frmMain
Private Sub StandardEditorToolStripMenuItem_MouseEnter(sender As Object, e As System.EventArgs) Handles StandardEditorToolStripMenuItem.MouseEnter
ToolStripMenuItem3.Text = "Standard Editor is for quick editing."
End Sub
Private Sub AdvancedEditorToolStripMenuItem_MouseEnter(sender As Object, e As System.EventArgs) Handles AdvancedEditorToolStripMenuItem.MouseEnter
ToolStripMenuItem3.Text = "Advanced Editor is for more in-depth editing."
End Sub
Private Sub frmMain_MouseEnter(sender As Object, e As System.EventArgs) Handles Me.MouseEnter
ToolStripMenuItem3.Text = "Select editing mode ..."
End Sub
Private Sub CancelToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CancelToolStripMenuItem.Click
End
End Sub
Private Sub CancelToolStripMenuItem_MouseEnter(sender As Object, e As System.EventArgs) Handles CancelToolStripMenuItem.MouseEnter
ToolStripMenuItem3.Text = "Exit editor."
End Sub
Private Sub StandardEditorToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles StandardEditorToolStripMenuItem.Click
Form1.Show()
Me.Hide()
End Sub
Private Sub AdvancedEditorToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AdvancedEditorToolStripMenuItem.Click
Form2.Show()
Me.Hide()
End Sub
End Class
Re: Find/Replace a 'block' of text in a text file?
For prob #1.. What about using MDI?
For prob #2... I bet it is open somewhere... Somewhere i'm betting you forgot to close the datastream...
Prob just a little hard to spot...
NOTE: Nowhere in your example code does it show any data being read... So noone would be able to help you with that even if they wanted to...
Re: Find/Replace a 'block' of text in a text file?
This is the code I have to open the CFG file to the datagrid (Form1)(Your code, elielCT):
Code:
Private Sub AxisToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AxisToolStripMenuItem.Click
CarName.Text = "Axis_V3"
OpenCFG.InitialDirectory = "C:\Program Files (x86)\Activision Value\Street Legal\cars\racers\" & CarName.Text & "\scripts\"
Dim fileselector As OpenFileDialog = Me.OpenCFG
Dim filePath As String
Dim fileReader As IO.StreamReader
Dim filedata As ArrayList = New ArrayList
fileselector.ShowDialog()
filePath = fileselector.FileName
fileselector.Dispose()
Me.FileSelected_Label.Text = filePath
Me.FileSelected_Label.Refresh()
fileReader = New IO.StreamReader(filePath)
DataViewer_ListBox.Items.Clear()
FileSelected_Label.Text = filePath
While Not fileReader.EndOfStream
filedata.Add(fileReader.ReadLine)
End While
fileReader.Close()
showData(filedata)
End Sub
To open the same file in a regular textbox (Form2), I used:
Code:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.ControlBox = False
Dim Reader As StreamReader = File.OpenText(Path1.Text)
On Error Resume Next
Dim FileText As String = Reader.ReadToEnd()
Reader.Close()
TextBox1.Text = FileText
End Sub
Private Sub SaveCFGFileToolStripMenuItem1_Click_1(sender As System.Object, e As System.EventArgs) Handles SaveCFGFileToolStripMenuItem1.Click
Dim txtwriter As TextWriter
If TextBox1.Text = "" Then
Exit Sub
End If
txtwriter = New StreamWriter(Path1.Text)
txtwriter.WriteLine(TextBox1.Text)
txtwriter.Close()
MsgBox("File saved!", MsgBoxStyle.Information, "Success!")
TextBox1.Refresh()
End Sub
Does this help any? Like I said, I'm still technically 'learning' .NET - I programmed in VB6 for years, though - I'm just having a hard time converting my ways of thinking LOL
Re: Find/Replace a 'block' of text in a text file?
This is the code I have to open the CFG file to the datagrid (Form1)(Your code, elielCT):
Code:
Private Sub AxisToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AxisToolStripMenuItem.Click
CarName.Text = "Axis_V3"
OpenCFG.InitialDirectory = "C:\Program Files (x86)\Activision Value\Street Legal\cars\racers\" & CarName.Text & "\scripts\"
Dim fileselector As OpenFileDialog = Me.OpenCFG
Dim filePath As String
Dim fileReader As IO.StreamReader
Dim filedata As ArrayList = New ArrayList
fileselector.ShowDialog()
filePath = fileselector.FileName
fileselector.Dispose()
Me.FileSelected_Label.Text = filePath
Me.FileSelected_Label.Refresh()
fileReader = New IO.StreamReader(filePath)
DataViewer_ListBox.Items.Clear()
FileSelected_Label.Text = filePath
While Not fileReader.EndOfStream
filedata.Add(fileReader.ReadLine)
End While
fileReader.Close()
showData(filedata)
End Sub
To open the same file in a regular textbox (Form2), I used:
Code:
Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.ControlBox = False
Dim Reader As StreamReader = File.OpenText(Path1.Text)
On Error Resume Next
Dim FileText As String = Reader.ReadToEnd()
Reader.Close()
TextBox1.Text = FileText
End Sub
Private Sub SaveCFGFileToolStripMenuItem1_Click_1(sender As System.Object, e As System.EventArgs) Handles SaveCFGFileToolStripMenuItem1.Click
Dim txtwriter As TextWriter
If TextBox1.Text = "" Then
Exit Sub
End If
txtwriter = New StreamWriter(Path1.Text)
txtwriter.WriteLine(TextBox1.Text)
txtwriter.Close()
MsgBox("File saved!", MsgBoxStyle.Information, "Success!")
TextBox1.Refresh()
End Sub
Does this help any? Like I said, I'm still technically 'learning' .NET - I programmed in VB6 for years, though - I'm just having a hard time converting my ways of thinking LOL