Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: elqueteconte en 23 Octubre 2015, 17:24 pm



Título: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 23 Octubre 2015, 17:24 pm
Saludos a todos;

El siguiente script hace un merge de archivos TXT:
Código
  1.   Public Sub FindAndMergeFiles(ByVal sourceDir As String)
  2.        Dim fileNames As String() =
  3.        {
  4.            "CM.txt", "GL.txt",
  5.            "IMP6000.txt", "IMP6001.txt", "IMP6002.txt", "IMP6003.txt"
  6.        }
  7.        Dim curFilename As String = String.Empty
  8.        For Each topDir As DirectoryInfo In New DirectoryInfo(sourceDir).GetDirectories("*", SearchOption.TopDirectoryOnly)
  9.            ' Elimino los archivos principales ("...\topDir\CM.txt", "...\topDir\GL.txt", etc...) de sesiones anteriores.
  10.            For Each txtfile As FileInfo In topDir.GetFiles("*.txt", SearchOption.TopDirectoryOnly)
  11.                If fileNames.Contains(txtfile.Name, StringComparer.OrdinalIgnoreCase) Then
  12.                    txtfile.Delete()
  13.                End If
  14.            Next txtfile
  15.            For Each subDir As DirectoryInfo In topDir.GetDirectories("*", SearchOption.AllDirectories)
  16.                For Each txtfile As FileInfo In subDir.GetFiles("*.txt", SearchOption.AllDirectories)
  17.                    If fileNames.Contains(txtfile.Name, StringComparer.OrdinalIgnoreCase) Then
  18.                        curFilename = fileNames.First(Function(filename) filename.Equals(txtfile.Name, StringComparison.OrdinalIgnoreCase))
  19.                        Using sr As StreamReader = txtfile.OpenText
  20.                            Using sw As New StreamWriter(Path.Combine(topDir.FullName, curFilename), append:=True, encoding:=Encoding.Default, bufferSize:=128)
  21.                                sw.WriteLine(sr.ReadToEnd)
  22.                            End Using ' sw
  23.                        End Using ' sr
  24.                    End If
  25.                Next txtfile
  26.            Next subDir
  27.        Next topDir
  28.  

Ahora bien en el formulario que usa ese script hay un selector que indica dos opciones A y B; donde si la opción B es la que ha sido seleccionada es nesario buscar en dos archivos particulares una palabra y cambiarla por otra, entiendo que la funcion sería mas o menos así:

Código
  1. Private Sub ReemplazaTexto(ByVal Fichero As String, ByVal Texto_Busca As String, ByVal Texto_Reemplaza As String)
  2.    Dim Reader As New StreamReader(Fichero)
  3.    Dim Content As String = Reader.ReadToEnd()
  4.    Reader.Close()
  5.    Content = Regex.Replace(Content, Texto_Busca, Texto_Reemplaza)
  6.    Dim Writer As New StreamWriter(FicheroNuevo)
  7.    Writer.Write(Content)
  8.    writer.Close()
  9. End Sub
  10.  

Ahora lo que quedaría es que despues que ejecuto el merge es preguntar que opción del combobox está seleccionada, que sería así:
Código
  1. 'El usuario selecciono la opcion para cambiar texto
  2. If ComboBox1.SelectedIndex = 0 Then
  3.          reemplazatexto("AR.txt","TXTB1","TXTN")
  4.          reemplazatexto("AR.txt","TXTB2","TXTN")
  5.          reemplazatexto("BR.txt","TXTB1","TXTN")
  6.          reemplazatexto("BR.txt","TXTB2","TXTN")
  7. Else          
  8.         return
  9. End If
  10.  

Creo que así sería; pero si alguien tiene uuna mejor idea será bien recibida.

Desde ya mil gracias.


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 23 Octubre 2015, 21:05 pm
El motor RegEx es lento. Si realmente estás usando patrones de expresiones regulares para buscar texto, o si quieres reemplazar texto sin diferenciar mayus/minus entonces te sugiero usar estas extensiones:

( La función StringExtensions.Replace es mucho más rápida que una expresión regular en modo IgnoreCase )

Código
  1. Imports System.Runtime.CompilerServices
  2.  
  3. Public Module StringExtensions
  4.  
  5.    <Extension>
  6.    Public Function ReplaceRegEx(ByVal sender As String,
  7.                                 ByVal findWhat As String,
  8.                                 ByVal replaceWith As String,
  9.                                 Optional ByVal regexOptions As RegexOptions =
  10.                                                RegularExpressions.RegexOptions.None) As String
  11.  
  12.        If String.IsNullOrEmpty(sender) Then
  13.            Return sender
  14.  
  15.        ElseIf String.IsNullOrEmpty(findWhat) Then
  16.            Throw New ArgumentNullException(paramName:="findWhat")
  17.  
  18.        Else
  19.            Return Regex.Replace(sender, findWhat, replaceWith, regexOptions)
  20.  
  21.        End If
  22.  
  23.    End Function
  24.  
  25.    <Extension>
  26.    Public Function Replace(ByVal sender As String,
  27.                            ByVal findWhat As String,
  28.                            ByVal replaceWith As String,
  29.                            ByVal comparisonType As StringComparison) As String
  30.  
  31.        If String.IsNullOrEmpty(sender) Then
  32.            Return sender
  33.  
  34.        ElseIf String.IsNullOrEmpty(findWhat) Then
  35.            Throw New ArgumentNullException(paramName:="findWhat")
  36.  
  37.        Else
  38.            Return StringExtensions.Replace(sender, findWhat, replaceWith, comparisonType, stringBuilderCapacity:=0)
  39.  
  40.        End If
  41.  
  42.    End Function
  43.  
  44.    ''' ----------------------------------------------------------------------------------------------------
  45.    ''' <remarks>
  46.    ''' Author: Elektro
  47.    ''' Orig. : http://www.codeproject.com/Articles/10890/Fastest-C-Case-Insenstive-String-Replace?msg=1835929#xx1835929xx
  48.    ''' </remarks>
  49.    ''' ----------------------------------------------------------------------------------------------------
  50.    ''' <param name="stringBuilderCapacity">
  51.    ''' The initial buffer size of the <see cref="Stringbuilder"/>.
  52.    ''' This parameter is reserved for testing purposes.
  53.    ''' </param>
  54.    ''' ----------------------------------------------------------------------------------------------------
  55.    <DebuggerHidden>
  56.    <DebuggerStepThrough>
  57.    <Extension>
  58.    Private Function Replace(ByVal sender As String,
  59.                             ByVal findWhat As String,
  60.                             ByVal replaceWith As String,
  61.                             ByVal comparisonType As StringComparison,
  62.                             ByVal stringBuilderCapacity As Integer) As String
  63.  
  64.        If String.IsNullOrEmpty(sender) Then
  65.            Return sender
  66.  
  67.        ElseIf String.IsNullOrEmpty(findWhat) Then
  68.            Throw New ArgumentNullException(paramName:="findWhat")
  69.  
  70.        Else
  71.            Dim posCurrent As Integer = 0
  72.            Dim lenPattern As Integer = findWhat.Length
  73.            Dim idxNext As Integer = sender.IndexOf(findWhat, comparisonType)
  74.            Dim result As New StringBuilder(capacity:=If(stringBuilderCapacity <= 0, Math.Min(4096, sender.Length), stringBuilderCapacity))
  75.  
  76.            While (idxNext >= 0)
  77.                result.Append(sender, posCurrent, (idxNext - posCurrent))
  78.                result.Append(replaceWith)
  79.  
  80.                posCurrent = (idxNext + lenPattern)
  81.                idxNext = sender.IndexOf(findWhat, posCurrent, comparisonType)
  82.            End While
  83.  
  84.            result.Append(sender, posCurrent, (sender.Length - posCurrent))
  85.  
  86.            Return result.ToString
  87.  
  88.        End If
  89.  
  90.    End Function
  91.  
  92. End Module



Citar
Código
  1. Private Sub ReemplazaTexto(ByVal Fichero As String, ByVal Texto_Busca As String, ByVal Texto_Reemplaza As String)
  2.    Dim Reader As New StreamReader(Fichero)
  3.    Dim Content As String = Reader.ReadToEnd()
  4.    Reader.Close()
  5.    Content = Regex.Replace(Content, Texto_Busca, Texto_Reemplaza)
  6.    Dim Writer As New StreamWriter(FicheroNuevo)
  7.    Writer.Write(Content)
  8.    writer.Close()
  9. End Sub

Usando el módulo de arriba, yo lo dejaría tal que así (pero sin los nombres en Español xD):
Código
  1. Private Sub ReemplazaTexto(ByVal fichero As String,
  2.                           ByVal texto_Busca As String, ByVal texto_Reemplaza As String,
  3.                           ByVal comparisonType As StringComparison)
  4.  
  5.    If Not File.Exists(fichero) Then
  6.        Throw New FileNotFoundException(message:="File not found", fileName:=fichero)
  7.  
  8.    Else
  9.        Dim txt As String = File.ReadAllText(fichero, Encoding.Default).
  10.                                 Replace(texto_Busca, texto_Reemplaza, comparisonType)
  11.  
  12.        File.WriteAllText(fichero, txt, Encoding.Default)
  13.  
  14.    End If
  15.  
  16. End Sub

EDITO: Pero vamos, si sabes que la palabra va a ser toda en mayúscula o minúscula o como sea entonces ignora el módulo de arriba y usa un String.Replace normal claro está.

Saludos!


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 23 Octubre 2015, 21:42 pm
Chamo de pana que tu comes .net....

Q arrech.... Tu codigo....

Tengo varias preguntas:
1.- Al momento de crear el módulo me da error con las variables RegexOptions y Regex; el compilador me indica que no están definidas.

2.- Como lo acoplo esa función en el script que hemos venido trabajando?
Aqui hago el llamado al merge de los archivos:
Código
  1. ' Merge text files.
  2.        DateUtil.FindAndMergeFiles(Me.fdg.SelectedPath)
  3.  

Luego de hacer l merge pregunto por el valor del combobox
Código
  1. 'El usuario selecciono la opcion para cambiar texto
  2. If ComboBox1.SelectedIndex = 0 Then
  3.          ReplaceText("GL.txt","TXT01","TXT1")
  4.          ReplaceText("GL.txt","TXT02","TXT1")
  5.          ReplaceText("IMP6000.txt","TXT01","TXT1")
  6.          ReplaceText("IMP6000.txt","TXT02","TXT1")
  7. Else          
  8.         return
  9. End If
  10.  

3.- La función ReplaceText (ya la puse en ingles jejejejejeje)
Código
  1.    Private Sub ReplaceText(ByVal txtfile As String,
  2.                               ByVal txtfind As String, ByVal txtreplace As String,
  3.                               ByVal comparisonType As StringComparison)
  4.         If Not File.Exists(txtfile) Then
  5.            Throw New FileNotFoundException(message:="File not found", fileName:=txtfile)
  6.         Else
  7.            Dim txt As String = File.ReadAllText(txtfile, Encoding.Default).
  8.                                     Replace(txtfind, txtreplace, comparisonType)
  9.             File.WriteAllText(txtfile, txt, Encoding.Default)
  10.         End If
  11.     End Sub
  12.  
iria dentro del formulario; correcto?

Mil gracias de nuevo pana.


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 24 Octubre 2015, 09:21 am
1.- Al momento de crear el módulo me da error con las variables RegexOptions y Regex; el compilador me indica que no están definidas.

Tienes que importar los espacios de nombres o NameSpaces necesarios.

Código
  1. Imports System.Text.RegularExpressions

Sinceramente, si tienes pensado seguir utilizando VB.Net para otro tipo de tareas en el futuro, entonces esto es algo a lo que te deberías acostumbrar a poder resolverlo por ti mismo ya que es una situación de lo más común.

Coloca por 1 o 2 segundos el puntero del mouse sobre la orden o el miembro que se marca en rojo en la IDE (en este caso la palabra "RegEx"), aparecerá un icono al final del nombre con una flechita, si le aprietas a la flecha aparecerá una lista con varias opciones resolutivas entre ellas importar "X" namespace (no siempre aparecerá esa opción, pero en este caso debería salir), si le pinchas automaticamente se añadirá la instrucción Imports que sea necesaria.



2.- Como lo acoplo esa función en el script que hemos venido trabajando?

Creo que te refieres a hacer algo así:

Código
  1. Sub...
  2.  
  3. 'El usuario selecciono la opcion para cambiar texto
  4. If (Me.ComboBox1.SelectedIndex = 0) Then
  5.    Dim comparisonType As StringComparison = StringComparison.OrdinalIgnoreCase
  6.    FindFileAndReplaceTextIn(sourceDir, "GL.txt", "TXT01", "TXT1", comparisonType)
  7.    FindFileAndReplaceTextIn(sourceDir, "GL.txt", "TXT02", "TXT1", comparisonType)
  8.    FindFileAndReplaceTextIn(sourceDir, "IMP6000.txt", "TXT01", "TXT1", comparisonType)
  9.    FindFileAndReplaceTextIn(sourceDir, "IMP6000.txt", "TXT02", "TXT1", comparisonType)
  10.  
  11. Else
  12.    Exit Sub
  13.  
  14. End If
  15.  
  16. End Sub
+
Código
  1. Public Sub FindFileAndReplaceTextIn(ByVal sourceDir As String, ByVal filenameFind As String,
  2.                                    ByVal txtfind As String, ByVal txtreplace As String,
  3.                                    ByVal comparisonType As StringComparison)
  4.  
  5.    For Each topDir As DirectoryInfo In New DirectoryInfo(sourceDir).GetDirectories("*", SearchOption.TopDirectoryOnly)
  6.  
  7.        For Each txtfile As FileInfo In topDir.GetFiles("*.txt", SearchOption.TopDirectoryOnly)
  8.  
  9.            If txtfile.Name.Equals(filenameFind, StringComparison.OrdinalIgnoreCase) Then
  10.                Dim txt As String = File.ReadAllText(txtfile.FullName, Encoding.Default).
  11.                                         Replace(txtfile.FullName, txtfind, txtreplace, comparisonType)
  12.  
  13.                File.WriteAllText(txtfile.FullName, txt, Encoding.Default)
  14.            End If
  15.  
  16.        Next txtfile
  17.  
  18.    Next topDir
  19.  
  20. End Sub

El método ReplaceText ya no sería necesario.



Citar
3.- La función ReplaceText (ya la puse en ingles jejejejejeje)

Genial, aunque no hacia falta, si te entiendes mejor con la programación en Español entonces no cambies tus hábitos por un comentario que hice, de todas formas así en Inglés está todo mucho mejor ...es algo positivo.



Citar
iria dentro del formulario; correcto?

Todo código que no forme parte del Form (como el módulo que compartí, o tus funciones de reempalzar texto y tal) deberías aislarlo de la class del form, en la medida de lo posible, es decir, las llamadas a esos métodos las realizas desde la Clas del Form claro está (Form1.vb o lo que sea), pero los bloques de código de esos métodos los declaras en módulos/classes distintas.

Saludos


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 26 Octubre 2015, 17:29 pm
Ante todo, gracias de nuevo Elektro;

Capté perfectamente el mensaje, de hecho te comparto lo que hice:
1.- En el módulo StringExtensions colgué la función FindFileAndReplaceTextIn
2.- En el módulo DateUtil colgué en la función FindAndMergeFiles justo despues de terminar con el último for la consulta al valor del ComboBox y si el valor es el esperado entonces llamo a la función FindFileAndReplaceTextIn que está en el otro módulo.

Pero hay un detalle y trate de solucionarlo con el mismo asistente que me recomendaste pero no funcionó con ello.

El detalle es que en la función FindFileAndReplaceTextIn se manejan 5 parámetros de los cuales hay uno llamado txtreplace que supuestamente es un String pero debería ser (segun el Visual) StringComparison pero cuando hago el cambo sugerido entonces en la sentencia donde hago el llamado:

Código
  1. FindFileAndReplaceTextIn(sourceDir, "GL.txt", "textbuscar", "textoreemplaza", comparisonType)
  2.  

Me da un warning y el Visual me sugiere que debo cambiarlo a:
Código
  1. FindFileAndReplaceTextIn(sourceDir, "GL.txt", "textbuscar", CType("textoreemplaza", StringComparison), comparisonType)
  2.  

Que es lo que realmente hice mal?
Porque me da esos warnings?

Desde ya mil gracias amigo.


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 26 Octubre 2015, 17:55 pm
Que es lo que realmente hice mal?
Porque me da esos warnings?

Supuestamente no estás haciendo nada mal y tampoco te debería saltar ningún warning.

Los 4 primeros parámetros del método FindFileAndReplaceTextIn son de tipo String, y el quinto parámetro es del tipo StringComparison, por ende, si tu le estás pasando 4 strings + un StringComparison entonces no entiendo en absoluto por que te salta el warning, ya que no debería.

Solo se me ocurre que hayas modificado la parametización del método FindFileAndReplaceTextIn cambiando el orden del último parámetro ...¿?

De todas formas, tengas el orden de los parámetros como lo tengas, siempre puedes usar parámetros nombrados (named parameters) para especificar estrictamente a que parámetro correspodne cada valor que le pasas al método:
Código
  1. FindFileAndReplaceTextIn(sourceDir:=sourceDir, filenameFind:="GL.txt",
  2.                         txtfind:="textbuscar", txtreplace:="textoreemplaza",
  3.                         comparisonType:=comparisonType)

Eso debería solucionar el problema, a menos que hayas modificado algo xD.

Saludos!


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 26 Octubre 2015, 20:38 pm
Saludos mi pana,

Cada consulta contigo es una clase de .net jejejejejeje  ;-)

Esta es la función
Código:
FindFileAndReplaceTextIn
que me pasaste:
Código
  1. Public Sub FindFileAndReplaceTextIn(ByVal sourceDir As String, ByVal filenameFind As String,
  2.                                    ByVal txtfind As String, ByVal txtreplace As String,
  3.                                    ByVal comparisonType As StringComparison)
  4.        For Each topDir As DirectoryInfo In New DirectoryInfo(sourceDir).GetDirectories("*", SearchOption.TopDirectoryOnly)
  5.            For Each txtfile As FileInfo In topDir.GetFiles("*.txt", SearchOption.TopDirectoryOnly)
  6.                If txtfile.Name.Equals(filenameFind, StringComparison.OrdinalIgnoreCase) Then
  7.                    Dim txt As String = File.ReadAllText(txtfile.FullName, Encoding.Default).
  8.                                             Replace(txtfile.FullName, txtfind, txtreplace, comparisonType)
  9.                    File.WriteAllText(txtfile.FullName, txt, Encoding.Default)
  10.                End If
  11.            Next txtfile
  12.        Next topDir
  13.    End Sub
  14.  

En la definición de los parámetros está txtreplace como
Código:
String
donde según entiendo debería ser
Código:
StringComparison
; ahora bien si lo cambio entonces en el llamado a la función me da otro warning. Precisamente con ese parámetro.

Entonces hago el llamado a la misma de la siguiente forma:
Código
  1. FindFileAndReplaceTextIn(sourceDir, "GL.txt", "AGENO-02", "AGEN-03", comparisonType)

Gracias nuevamente.





Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 26 Octubre 2015, 23:02 pm
Supuestamente no estás haciendo nada mal y tampoco te debería saltar ningún warning.

Los 4 primeros parámetros del método FindFileAndReplaceTextIn son de tipo String, y el quinto parámetro es del tipo StringComparison, por ende, si tu le estás pasando 4 strings + un StringComparison entonces no entiendo en absoluto por que te salta el warning, ya que no debería.

Solo se me ocurre que hayas modificado la parametización del método FindFileAndReplaceTextIn cambiando el orden del último parámetro ...¿?

De todas formas, tengas el orden de los parámetros como lo tengas, siempre puedes usar parámetros nombrados (named parameters) para especificar estrictamente a que parámetro correspodne cada valor que le pasas al método:
Código
  1. FindFileAndReplaceTextIn(sourceDir:=sourceDir, filenameFind:="GL.txt",
  2.                         txtfind:="textbuscar", txtreplace:="textoreemplaza",
  3.                         comparisonType:=comparisonType)

Eso debería solucionar el problema, a menos que hayas modificado algo xD.

Saludos!

Saludos mi pana,

Probé exactamente lo que indicas y me dió error.
Este es el error:

Código:
BC30512 Option Strict On disallows implicit conversions from 'String' to 'StringComparison'. WindowsApplication6 C:\Users\liderapp\Documents\Visual Studio 2015\Projects\WindowsApplication6\WindowsApplication6\StringExtensions.vb 91

Al irme a la linea 91 el error lo da aqui:
Código:
Replace(txtfile.FullName, txtfind, [b]txtreplace[/b], comparisonType)

Que sugieres hermano...?



Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 27 Octubre 2015, 02:16 am
Imagino que estas usando esta extensión de método?:

Cita de: http://foro.elhacker.net/net/cambiar_palabras_de_un_archivo_txt-t443323.0.html;msg2044424#msg2044424
Código
  1.    Private Function Replace(ByVal sender As String,
  2.                             ByVal findWhat As String,
  3.                             ByVal replaceWith As String,
  4.                             ByVal comparisonType As StringComparison,
  5.                             ByVal stringBuilderCapacity As Integer) As String
  6.  
  7. ...
  8.  
  9.    End Function

La cual por cierto no se por que la declaré von visibilidad Private, modifica el keyword Private por Public para poder utilizarla.

Aparte, el parámetro sender se asigna automaticamente, debes ignorarlo y dejarlo así:
Código
  1. ...Replace(txtfind, txtreplace, comparisonType, 128)

saludos


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 27 Octubre 2015, 17:04 pm
Imagino que estas usando esta extensión de método?:

La cual por cierto no se por que la declaré von visibilidad Private, modifica el keyword Private por Public para poder utilizarla.

Aparte, el parámetro sender se asigna automaticamente, debes ignorarlo y dejarlo así:
Código
  1. ...Replace(txtfind, txtreplace, comparisonType)

saludos

Buenos días bro;

Si estoy usando tal cual lo que me diste.

La función queda así:

Código
  1.    Private Function Replace(ByVal sender As String,
  2.                             ByVal findWhat As String,
  3.                             ByVal replaceWith As String,
  4.                             ByVal comparisonType As StringComparison,
  5.                             ByVal stringBuilderCapacity As Integer) As String
  6.  
  7.        If String.IsNullOrEmpty(sender) Then
  8.            Return sender
  9.  
  10.        ElseIf String.IsNullOrEmpty(findWhat) Then
  11.            Throw New ArgumentNullException(paramName:="findWhat")
  12.  
  13.        Else
  14.            Return StringExtensions.Replace(findWhat, replaceWith, comparisonType)
  15.  
  16.        End If
  17.  

Ahora hay otro detalle del que me estoy dando cuenta; tienes dos funciones llamas igual, una privada y otra publica; pero al hacerlas ambas Publicas el VS da error.

Estas son las funciones:
Código
  1.    Public Function Replace(ByVal sender As String,
  2.                            ByVal findWhat As String,
  3.                            ByVal replaceWith As String,
  4.                            ByVal comparisonType As StringComparison) As String
  5.        If String.IsNullOrEmpty(sender) Then
  6.            Return sender
  7.        ElseIf String.IsNullOrEmpty(findWhat) Then
  8.            Throw New ArgumentNullException(paramName:="findWhat")
  9.        Else
  10.            Return StringExtensions.Replace(sender, findWhat, replaceWith, comparisonType, stringBuilderCapacity:=0)
  11.        End If
  12.    End Function
  13.  

Esta es la otra:

Código
  1. Private Function Replace(ByVal sender As String,
  2.                             ByVal findWhat As String,
  3.                             ByVal replaceWith As String,
  4.                             ByVal comparisonType As StringComparison,
  5.                             ByVal stringBuilderCapacity As Integer) As String
  6.        If String.IsNullOrEmpty(sender) Then
  7.            Return sender
  8.        ElseIf String.IsNullOrEmpty(findWhat) Then
  9.            Throw New ArgumentNullException(paramName:="findWhat")
  10.        Else
  11.            Dim posCurrent As Integer = 0
  12.            Dim lenPattern As Integer = findWhat.Length
  13.            Dim idxNext As Integer = sender.IndexOf(findWhat, comparisonType)
  14.            Dim result As New StringBuilder(capacity:=If(stringBuilderCapacity <= 0, Math.Min(4096, sender.Length), stringBuilderCapacity))
  15.            While (idxNext >= 0)
  16.                result.Append(sender, posCurrent, (idxNext - posCurrent))
  17.                result.Append(replaceWith)
  18.                posCurrent = (idxNext + lenPattern)
  19.                idxNext = sender.IndexOf(findWhat, posCurrent, comparisonType)
  20.            End While
  21.            result.Append(sender, posCurrent, (sender.Length - posCurrent))
  22.            Return result.ToString
  23.        End If
  24.    End Function
  25.  

Gracias mil de nuevo amigo.


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 27 Octubre 2015, 18:49 pm
Tienes razón, no me di cuenta que declaré dos funciones con las prisas xD

Reectifico lo que dije aquí:
Citar
La cual por cierto no se por que la declaré von visibilidad Private, modifica el keyword Private por Public para poder utilizarla.

Está todo bien, solo que tienes que ignorar eso último que dije, tienes que usar la otra función ...la que ya es publica, pues esa función llama a la función privada.

Saludos


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 27 Octubre 2015, 22:19 pm
Tienes razón, no me di cuenta que declaré dos funciones con las prisas xD

Reectifico lo que dije aquí:
Está todo bien, solo que tienes que ignorar eso último que dije, tienes que usar la otra función ...la que ya es publica, pues esa función llama a la función privada.

Saludos

El hecho de poder decirte que hay errores me apena... jajajajajaja

Pues te cuento que ya no da error el compilador pero cuando ejecuto el utilitario me está dando un System.StackOverflowException o pila sobrecargada en
Código:
   Public Function Replace(ByVal sender As String,
                             ByVal findWhat As String,
                             ByVal replaceWith As String,
                             ByVal comparisonType As StringComparison,
                             ByVal stringBuilderCapacity As Integer) As String

Estaba investigando y encuentro en el VS el siguiente mensaje:
The maximum number of stack frames supported by Visual Studio has been exceeded.   

Existe alguna forma de incrementar ese parámetro?
o alguna alternativa para evitar este overflow?

Gracias de nuevo mi pana....


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 28 Octubre 2015, 03:29 am
cuando ejecuto el utilitario me está dando un System.StackOverflowException

Esa excepción es síntoma de estar utilizando prácticas recursivas, por algún método/algoritmo con una recursividad excesiva y/o infinita la cual con sus llamadas colapsa el tamaño de la pila o stack, provocando así un overflow.

No puedo reproducir el conflicto con el código que te mostré en lo que denominariamos "circunstancias normales" (no llevando al límite las capacidades para provocar un stack-overflow intencionado).

Muestra el código que estás utilizando ahora.

Por cierto, ¿de cuantos archivos de texto (o veces que se llama el método "Replace" y se adjunta texto al objeto "StringBuilder") estamos hablando exactamente?, es que, para que te diera esa excepción debería ser un número de veces colosal, pero no descartaré la posibilidad ya que no se cuanta magnitud de datos estás trabajando.

Saludos!


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 28 Octubre 2015, 13:32 pm
Esa excepción es síntoma de estar utilizando prácticas recursivas, por algún método/algoritmo con una recursividad excesiva y/o infinita la cual con sus llamadas colapsa el tamaño de la pila o stack, provocando así un overflow.

No puedo reproducir el conflicto con el código que te mostré en lo que denominariamos "circunstancias normales" (no llevando al límite las capacidades para provocar un stack-overflow intencionado).

Muestra el código que estás utilizando ahora.

Por cierto, ¿de cuantos archivos de texto (o veces que se llama el método "Replace" y se adjunta texto al objeto "StringBuilder") estamos hablando exactamente?, es que, para que te diera esa excepción debería ser un número de veces colosal, pero no descartaré la posibilidad ya que no se cuanta magnitud de datos estás trabajando.

Saludos!

Buenos días bro...

Feliz día del Ingeniero!

Hagamos algo mejor...

Te voy a enviar en un PM un enlace para que bajes los archivos y la solucion.

Saludos y de nuevo mil gracias.



Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 30 Octubre 2015, 15:40 pm
Esa excepción es síntoma de estar utilizando prácticas recursivas, por algún método/algoritmo con una recursividad excesiva y/o infinita la cual con sus llamadas colapsa el tamaño de la pila o stack, provocando así un overflow.

No puedo reproducir el conflicto con el código que te mostré en lo que denominariamos "circunstancias normales" (no llevando al límite las capacidades para provocar un stack-overflow intencionado).

Muestra el código que estás utilizando ahora.

Por cierto, ¿de cuantos archivos de texto (o veces que se llama el método "Replace" y se adjunta texto al objeto "StringBuilder") estamos hablando exactamente?, es que, para que te diera esa excepción debería ser un número de veces colosal, pero no descartaré la posibilidad ya que no se cuanta magnitud de datos estás trabajando.

Saludos!

Saludos mi amigo,

Cuando puedas dale un vistazo al mensaje privado que te envié.

Gracias.



Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 30 Octubre 2015, 23:28 pm
Para reproducir el error haz lo siguiente ejecuta el script y en Empresa selecciona Mi Diario.

El problema está aquí:

Código
  1.            If (cb.SelectedIndex = 1) Then
  2.                'MessageBox.Show("Selecciono {0}", "Mensaje", MessageBoxButtons.OK, MessageBoxIcon.Error)
  3.                'cmbemp.Focus()
  4.                Dim comparisonType As StringComparison = StringComparison.OrdinalIgnoreCase
  5.                FindFileAndReplaceTextIn(sourceDir, "GL.txt", "MCBO-02", "MBO-03", comparisonType)
  6.                FindFileAndReplaceTextIn(sourceDir, "GL.txt", "MCBO-03", "MBO-03", comparisonType)
  7.                FindFileAndReplaceTextIn(sourceDir, "IMP6000.txt", "TXT01", "MBO-03", comparisonType)
  8.                FindFileAndReplaceTextIn(sourceDir, "IMP6000.txt", "TXT02", "MBO-03", comparisonType)
  9.            Else
  10.                Exit Sub
  11.            End If

Código
  1.        Public Sub FindFileAndReplaceTextIn(...)
  2.         ...
  3.             Dim txt As String = File.ReadAllText(txtfile.FullName, Encoding.Default).
  4.                                      Replace(txtfind, txtreplace, comparisonType, 128)
  5.         ...
  6.        End Sub

Código
  1.        Public Function Replace(...) As String
  2.  
  3.                Return StringExtensions.Replace(sender, findWhat, replaceWith, comparisonType, stringBuilderCapacity:=0)
  4.  
  5.        End Function

La función Replace se llama a si misma de forma infinita, y eso causa el colapso de la pila.

Se te pasó por alto a ti o a mi añadir la otra función que compartí, el "Replace" que era privado.



Para solucionarlo, reemplaza esto:
Código
  1.        Public Sub FindFileAndReplaceTextIn(...)
  2.         ...
  3.             Dim txt As String = File.ReadAllText(txtfile.FullName, Encoding.Default).
  4.                                      Replace(txtfind, txtreplace, comparisonType, 128)
  5.         ...
  6.        End Sub

por esto otro:

Código
  1.        Public Sub FindFileAndReplaceTextIn(...)
  2.         ...
  3.             Dim txt As String = File.ReadAllText(txtfile.FullName, Encoding.Default).
  4.                                      Replace(txtfind, txtreplace, comparisonType)
  5.         ...
  6.        End Sub

Y reemplaza el contenido del modulo "StringExtensions", por esto:

Código
  1. ' ESTE MODULO ESTÁ INCOMPLETO, SOLO LE AÑADÍ LAS FUNCIOENS DE REEMPLAZAMIENTO DE TEXTO.
  2. ' SI QUIERES EL CÓDIGO FUENTE COMPLETO CON MÁS FUNCIONES INTERESANTES, PUEDES DESCARGARLO AQUÍ:
  3. ' https://github.com/ElektroStudios/VBNetSnippets/blob/master/String/String%20Extensions.vb
  4.  
  5. #Region " Public Members Summary "
  6.  
  7. #Region " Functions "
  8.  
  9. ' String.Replace(String, String, StringComparison) As String
  10. ' String.ReplaceRegEx(String, String, RegExOptions) As String
  11.  
  12. #End Region
  13.  
  14. #End Region
  15.  
  16. #Region " Option Statements "
  17.  
  18. Option Strict On
  19. Option Explicit On
  20. Option Infer Off
  21.  
  22. #End Region
  23.  
  24. #Region " Imports "
  25.  
  26. Imports System
  27. Imports System.Linq
  28. Imports System.Diagnostics
  29. Imports System.Runtime.CompilerServices
  30. Imports System.Text
  31. Imports System.Text.RegularExpressions
  32.  
  33. #End Region
  34.  
  35. Namespace Tools
  36.  
  37.    ''' ----------------------------------------------------------------------------------------------------
  38.    ''' <summary>
  39.    ''' Contains custom extension methods to use with a <see cref="String"/>.
  40.    ''' </summary>
  41.    ''' ----------------------------------------------------------------------------------------------------
  42.    Public Module StringExtensions
  43.  
  44. #Region " Public Extension Methods "
  45.  
  46.        ''' ----------------------------------------------------------------------------------------------------
  47.        ''' <summary>
  48.        ''' Replaces text using a regular expression.
  49.        ''' </summary>
  50.        ''' ----------------------------------------------------------------------------------------------------
  51.        ''' <example> This is a code example.
  52.        ''' <code>
  53.        ''' Dim str As String = "Hello World!".ReplaceRegEx("world", "kitty", RegexOptions.IgnoreCase)
  54.        ''' </code>
  55.        ''' </example>
  56.        ''' ----------------------------------------------------------------------------------------------------
  57.        ''' <param name="sender">
  58.        ''' The source <see cref="String"/>.
  59.        ''' </param>
  60.        '''
  61.        ''' <param name="findWhat">
  62.        ''' The <see cref="Regex"/> find expression.
  63.        ''' </param>
  64.        '''
  65.        ''' <param name="regexOptions">
  66.        ''' The <see cref="RegexOptions"/>.
  67.        ''' </param>
  68.        ''' ----------------------------------------------------------------------------------------------------
  69.        ''' <exception cref="ArgumentNullException">
  70.        ''' findWhat
  71.        ''' </exception>
  72.        ''' ----------------------------------------------------------------------------------------------------
  73.        ''' <returns>
  74.        ''' The replaced string.
  75.        ''' </returns>
  76.        ''' ----------------------------------------------------------------------------------------------------
  77.        <DebuggerStepThrough>
  78.        <Extension>
  79.        Public Function ReplaceRegEx(ByVal sender As String,
  80.                                     ByVal findWhat As String,
  81.                                     ByVal replaceWith As String,
  82.                                     Optional ByVal regexOptions As RegexOptions =
  83.                                                    RegularExpressions.RegexOptions.None) As String
  84.  
  85.            If String.IsNullOrEmpty(sender) Then
  86.                Return sender
  87.  
  88.            ElseIf String.IsNullOrEmpty(findWhat) Then
  89.                Throw New ArgumentNullException(paramName:="findWhat")
  90.  
  91.            Else
  92.                Return Regex.Replace(sender, findWhat, replaceWith, regexOptions)
  93.  
  94.            End If
  95.  
  96.        End Function
  97.  
  98.        ''' ----------------------------------------------------------------------------------------------------
  99.        ''' <summary>
  100.        ''' Replaces text using the specified string comparison type.
  101.        ''' </summary>
  102.        ''' ----------------------------------------------------------------------------------------------------
  103.        ''' <example> This is a code example.
  104.        ''' <code>
  105.        ''' Dim str As String = "Hello World!".Replace("world", "kitty", StringComparison.OrdinalIgnoreCase)
  106.        ''' </code>
  107.        ''' </example>
  108.        ''' ----------------------------------------------------------------------------------------------------
  109.        ''' <param name="sender">
  110.        ''' The source <see cref="String"/>.
  111.        ''' </param>
  112.        '''
  113.        ''' <param name="findWhat">
  114.        ''' The <see cref="Regex"/> find expression.
  115.        ''' </param>
  116.        '''
  117.        ''' <param name="comparisonType">
  118.        ''' The string comparison type.
  119.        ''' </param>
  120.        ''' ----------------------------------------------------------------------------------------------------
  121.        ''' <exception cref="ArgumentNullException">
  122.        ''' findWhat
  123.        ''' </exception>
  124.        ''' ----------------------------------------------------------------------------------------------------
  125.        ''' <returns>
  126.        ''' The replaced string.
  127.        ''' </returns>
  128.        ''' ----------------------------------------------------------------------------------------------------
  129.        <DebuggerStepThrough>
  130.        <Extension>
  131.        Public Function Replace(ByVal sender As String,
  132.                                ByVal findWhat As String,
  133.                                ByVal replaceWith As String,
  134.                                ByVal comparisonType As StringComparison) As String
  135.  
  136.            If String.IsNullOrEmpty(sender) Then
  137.                Return sender
  138.  
  139.            ElseIf String.IsNullOrEmpty(findWhat) Then
  140.                Throw New ArgumentNullException(paramName:="findWhat")
  141.  
  142.            Else
  143.                Return StringExtensions.InternalReplace(sender, findWhat, replaceWith, comparisonType, stringBuilderCapacity:=-1)
  144.  
  145.            End If
  146.  
  147.        End Function
  148.  
  149. #End Region
  150.  
  151. #Region " Private Methods "
  152.  
  153.        ''' ----------------------------------------------------------------------------------------------------
  154.        ''' <summary>
  155.        ''' Replaces text using the specified string comparison type.
  156.        ''' </summary>
  157.        ''' ----------------------------------------------------------------------------------------------------
  158.        ''' <example> This is a code example.
  159.        ''' <code>
  160.        ''' Dim str As String = "Hello World!".Replace("world", "kitty", StringComparison.OrdinalIgnoreCase)
  161.        ''' </code>
  162.        ''' </example>
  163.        ''' ----------------------------------------------------------------------------------------------------
  164.        ''' <param name="sender">
  165.        ''' The source <see cref="String"/>.
  166.        ''' </param>
  167.        '''
  168.        ''' <param name="findWhat">
  169.        ''' The <see cref="Regex"/> find expression.
  170.        ''' </param>
  171.        '''
  172.        ''' <param name="comparisonType">
  173.        ''' The string comparison type.
  174.        ''' </param>
  175.        '''
  176.        ''' <param name="stringBuilderCapacity">
  177.        ''' The initial buffer size of the <see cref="Stringbuilder"/>.
  178.        ''' This parameter is reserved for testing purposes.
  179.        ''' </param>
  180.        ''' ----------------------------------------------------------------------------------------------------
  181.        ''' <returns>
  182.        ''' The replaced string.
  183.        ''' </returns>
  184.        ''' ----------------------------------------------------------------------------------------------------
  185.        <DebuggerHidden>
  186.        <DebuggerStepThrough>
  187.        Private Function InternalReplace(ByVal sender As String,
  188.                                         ByVal findWhat As String,
  189.                                         ByVal replaceWith As String,
  190.                                         ByVal comparisonType As StringComparison,
  191.                                         ByVal stringBuilderCapacity As Integer) As String
  192.  
  193.            Dim posCurrent As Integer = 0
  194.            Dim lenPattern As Integer = findWhat.Length
  195.            Dim idxNext As Integer = sender.IndexOf(findWhat, comparisonType)
  196.            Dim result As New StringBuilder(capacity:=If(stringBuilderCapacity <= 0, Math.Min(4096, sender.Length), stringBuilderCapacity))
  197.  
  198.            While (idxNext >= 0)
  199.                result.Append(sender, posCurrent, (idxNext - posCurrent))
  200.                result.Append(replaceWith)
  201.  
  202.                posCurrent = (idxNext + lenPattern)
  203.                idxNext = sender.IndexOf(findWhat, posCurrent, comparisonType)
  204.            End While
  205.  
  206.            result.Append(sender, posCurrent, (sender.Length - posCurrent))
  207.  
  208.            Return result.ToString
  209.  
  210.        End Function
  211.  
  212. #End Region
  213.  
  214.    End Module
  215.  
  216. End Namespace

Saludos


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 3 Noviembre 2015, 13:31 pm
Saludos amigo,

Estoy testeando la app y le he encontrado un solo detalle y es que luego de que hace el merge de los archivos está dejando una linea en blanco en el archivo final (no se si me explico?)  :-\

Revisando y estudiando el código me doy cuenta que el problema está en la función FindAndMergeFiles, pienso que despues de hacer el merge hay que hacer un barrido del mismo archivo para quitar las lineas vacias, la rutina por lo que he leido sería mas o menos así:
Código
  1. archivotxt = Regex.Replace(archivotxt, "^\r|\n\r|\n$", "")

La pregunta sería en que parte y como incluiría esa sentencia en la funcion FindAndMergeFiles.

Desde ya mil gracias de nuevo amigo.





Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 5 Noviembre 2015, 16:39 pm
RegEx es lento, intenta evitarlo.

En el método FindAndMergeFiles realiza esta modificación:

Código
  1. Using sr As StreamReader = txtfile.OpenText
  2.  
  3.    Using sw As New StreamWriter(Path.Combine(topDir.FullName, curFilename), append:=True, encoding:=Encoding.Default, bufferSize:=4096)
  4.  
  5.        Dim content As String = sr.ReadToEnd.Replace(Environment.NewLine, "")
  6.        If Not String.IsNullOrEmpty(content) Then
  7.            sw.WriteLine(content)
  8.        End If
  9.  
  10.    End Using ' sw
  11.  
  12. End Using ' sr

La linea que queda en blanco al final del archivo es normal, ya que se está llamando al método WriteLine.

Saludos


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 5 Noviembre 2015, 16:49 pm
RegEx es lento, intenta evitarlo.

En el método FindAndMergeFiles realiza esta modificación:

Código
  1. Using sr As StreamReader = txtfile.OpenText
  2.  
  3.    Using sw As New StreamWriter(Path.Combine(topDir.FullName, curFilename), append:=True, encoding:=Encoding.Default, bufferSize:=4096)
  4.  
  5.        Dim content As String = sr.ReadToEnd.Replace(Environment.NewLine, "")
  6.        If Not String.IsNullOrEmpty(content) Then
  7.            sw.WriteLine(content)
  8.        End If
  9.  
  10.    End Using ' sw
  11.  
  12. End Using ' sr

La linea que queda en blanco al final del archivo es normal, ya que se está llamando al método WriteLine.

Saludos

Saludos Elektro;

Gracias por responder.

He aplicado el cambio y hace tan bien el trabajo que hasta quita el espacio de fin de registro y junta las lineas ;-), es decir, no toma en cuenta el fin del registro o linea, sino que al final de la linea toma la de abajo y lo concatena con la primera y así sucesivamente.

La idea es que quite las lineas en blanco pero respete la estructura del registro

Gracias mil de nuevo hermano por todo tu apoyo y colaboración.

Ejemplo:
Estado Inicial
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON

CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON

CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON


Estado Final
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON
CAMPO1;CAMPO2;CAMPO3;CAMPO4;CAMPO5;CAMPON


Espero haberme explicado.

Gracias de nuevo....



Título: Re: Cambiar palabras de un archivo TXT
Publicado por: Eleкtro en 5 Noviembre 2015, 17:56 pm
prueba con :

Código
  1. sw.WriteLine(content & Environment.NewLine)

Saludos


Título: Re: Cambiar palabras de un archivo TXT
Publicado por: elqueteconte en 5 Noviembre 2015, 21:29 pm
prueba con :

Código
  1. sw.WriteLine(content & Environment.NewLine)

Saludos

No sirvió con eso pues me colocaba una linea con el registro y una linea vacia.

Investigando logré encontrar un código con el que sí funcionó; entonces cambié esto:

Código
  1. Dim content As String = sr.ReadToEnd.Replace(Environment.NewLine, "")
  2. If Not String.IsNullOrEmpty(content) Then
  3.     sw.WriteLine(content & Environment.NewLine)
  4. End If
  5.  

Por esto:
Código
  1. While Not sr.EndOfStream
  2.   Dim content As String = sr.ReadLine
  3.   If content.Length > 0 Then
  4.      sw.WriteLine(content)
  5. End While
  6.  

Que te parece?


Con esto está haciendo lo que inicialmente se me pidio, ahora tengo que ir con la segunda fase del esto que se está convirtiendo en un proyecto muy interesante.

Te agradezco la ayud que me haz brindado hasta este momento y espero poder seguir contando con ella.

Gracias mil de nuevo.