web-dev-qa-db-ja.com

VB.NETの1行のコードで文字列の複数の文字を置き換える

VB.NETを使用して、文字列内の一連の文字を1行のコードで置き換えることができるようにしたいと考えています。

つまり、次のようなものです:

Dim charsToReplace as string = "acegi"
Dim stringToBeReplaced as string = "abcdefghijklmnop"

charsToReplace.ToArray().ForEach(Function (c) stringTobeReplaced = stringTobeReplaced.Replace(c, ""))

ただし、これは機能しません。

以下は機能しますが、文字列をクラスレベルの変数にしたくありません。

 Sub Main()
    Dim toReplace As String = "acegikmoq"

    Console.WriteLine(mainString)
    Dim chars As List(Of Char) = toReplace.ToList()
    chars.ForEach(AddressOf replaceVal)

    Console.WriteLine(mainString)
    Console.ReadLine()
End Sub

Dim mainString As String = "this is my string that has values in it that I am going to quickly replace all of..."

Sub replaceVal(ByVal c As Char)
    mainString = mainString.Replace(c, "")
End Sub

これはできますか?

13
hitch

これを正しく読んだ場合、文字列から文字のリストを削除しようとしていることになります。これは、RegExに適しています。

Console.WriteLine(Regex.Replace("abcdefghijklmnop", "[acegi]", string.Empty))

(System.Text.RegularExpressionsをインポートする必要があります)

26
Jon Galloway

RegExアプローチが最も適していますが、私が実際に言う必要があるのは次のとおりです。

メンテナンス開発者の愛情を込めて、これを1行のコードにまとめるのに熱中しないでください。 1つのメソッド呼び出しがあなたの本当の目標です。結局、1行に1組の呼び出しを積み上げて1行だと言うと、自分の足で撃ちます。

8
STW

LINQは正規表現よりも優れていると彼が言ったので、私はBittercodeを信じませんでした。だから念のために少しテストをしました。

これを行う方法の3つの例:

Dim _invalidChars As Char() = New Char() {"j"c, "a"c, "n"c}
Dim _textToStrip As String = "The quick brown fox jumps over the lazy dog"

Private Sub btnStripInvalidCharsLINQ_Click(sender As System.Object, e As System.EventArgs) Handles btnStripInvalidCharsLINQ.Click
    Dim stripped As String = String.Empty
    Dim sw As Stopwatch = Stopwatch.StartNew
    For i As Integer = 0 To 10000
        stripped = _textToStrip.Where(Function(c As Char) Not _invalidChars.Contains(c)).ToArray
    Next
   sw.Stop()

    lblStripInvalidCharsLINQ.Text = _stripped & " - in " & sw.Elapsed.TotalMilliseconds & " ms"
End Sub

Private Sub btnStripInvalidCharsFOR_Click(sender As System.Object, e As System.EventArgs) Handles btnStripInvalidCharsFOR.Click
    Dim stripped As String = String.Empty
    Dim sw As Stopwatch = Stopwatch.StartNew
    stripped = _textToStrip
    For i As Integer = 0 To 10000
        For Each c As Char In _invalidChars
            stripped = stripped.Replace(c, "")
        Next
    Next
    sw.Stop()

    lblStipInvalidcharsFor.Text = stripped & " - in " & sw.Elapsed.TotalMilliseconds & " ms"
End Sub

Private Sub btnStripInvalidCharsREGEX_Click(sender As System.Object, e As System.EventArgs) Handles btnStripInvalidCharsREGEX.Click
    Dim stripped As String = String.Empty
    Dim sw As Stopwatch = Stopwatch.StartNew
    For i As Integer = 0 To 10000
        stripped = Regex.Replace(_textToStrip, "[" & New String(_invalidChars) & "]", String.Empty)
    Next
    sw.Stop()

    lblStripInvalidCharsRegex.Text = stripped & " - in " & sw.Elapsed.TotalMilliseconds & " ms"
End Sub

結果:

Performance results

したがって、string.replaceを使用したforループは、他のすべてのメソッドよりも優れています。

このため、文字列オブジェクトに拡張関数を作成します。

Module StringExtensions
<Extension()> _
Public Function ReplaceAll(ByVal InputValue As String, ByVal chars As Char(), replaceWith As Char) As String
    Dim ret As String = InputValue
    For Each c As Char In chars
        ret = ret.Replace(c, replaceWith)
    Next
    Return ret
End Function

次に、この関数をナイスで読みやすいように1行で使用できます。

_textToStrip.ReplaceAll(_invalidChars, CChar(String.Empty))
5
JDC

Stringクラスには、これを行うためのreplaceメソッドがあります。次のように使用できます。

YourString = YourString.Replace("OldValue", "NewValue")
1
danish

私はJon Gallowayのアプローチをお勧めします。正規表現が適切な方法であり、将来の開発者はそれを感謝します:)-Linqで解決することも難しい問題ではありません。これを行うための(テストされていない)C#コードを次に示します。

string stringToBeReplaced = "abcdefghijklmnop";
string charsToReplace = "acegi";
stringToBeReplaced = new String(stringToBeReplaced.Where(c => !charsToReplace.Any(rc => c == rc)).ToArray());

パフォーマンスが問題である場合、このコードはおそらく正規表現の同等のものよりわずかに優れたパフォーマンスを発揮すると思います。

1
Bittercoder

本当にそのコードを使用したい場合、行ステートメントを繰り返す最良の方法は何ですか?

Sub Main() 

    Dim myString As String = Nothing
    Dim finalString As String = Nothing
    Console.Write("Please enter a string: ") 'your free to put anything
    myString = Console.ReadLine()
    finalString = myString.Replace("0", "")
    myString = finalString
    finalString = myString.Replace("1", "")
    myString = finalString
    finalString = myString.Replace("2", "")
    myString = finalString
    finalString = myString.Replace("3", "")
    myString = finalString
    finalString = myString.Replace("4", "")
    myString = finalString
    finalString = myString.Replace("5", "")
    myString = finalString
    finalString = myString.Replace("6", "")
    myString = finalString
    finalString = myString.Replace("7", "")
    myString = finalString
    finalString = myString.Replace("8", "")
    myString = finalString
    finalString = myString.Replace("9", "")
    Console.WriteLine(finalString)
    Console.ReadLine()
End Sub

例:入力した場合:012ALP456HA90BET678出力はALPHABETになります。

0
user1982529
Public Function SuperReplace(ByRef field As String, ByVal ReplaceString As String) As String
  ' Size this as big as you need... it is zero-based by default'
  Dim ReplaceArray(4) As String

  'Fill each element with the character you need to replace'

  ReplaceArray(0) = "WARD NUMBER "
  ReplaceArray(1) = "WN "
  ReplaceArray(2) = "WARD NO "
  ReplaceArray(3) = "WARD-"
  ReplaceArray(4) = "WARD "

  Dim i As Integer
  For i = LBound(ReplaceArray) To UBound(ReplaceArray)
    field = Replace(field, ReplaceArray(i), ReplaceString)
    Next i
  SuperReplace = field
End Function
0
Ashutosh
Private Sub cmdTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdTest.Click
    Dim s As String = "México Juárez índice recúrso dirección"
    Dim arr() As String = {"á", "é", "í", "ó", "ú", "Ñ", "ñ"}
    Dim rep() As String = {"a", "e", "i", "o", "u", "N", "n"}
    Dim i As Integer = Nothing

    For i = 0 To UBound(arr)
        s = Replace(s, arr(i), rep(i))
    Next

    MsgBox(s)

End Sub
0
Diprotask