如何使用特定字符连接 RichTextBox 中的选定行并替换现有行?

How to join selected lines in a RichTextBox with a specific character and replace the existing lines?

我想加入 RichTextBox 中的选定行并用特定字符分隔这两行。

The situation is dire
But momma raised up a fighter
It's all come down to the wire
But the come-up is higher

结果:

The situation is dire - But momma raised up a fighter

It's all come down to the wire - But the come-up is higher

生成的新行应替换控件中的现有行。

试试这个:

Dim StartSelection As Integer = RichTextBox1.SelectionStart
    Dim EndSelection As Integer = RichTextBox1.SelectionStart + RichTextBox1.SelectionLength
    Dim StartLine As Integer = 0
    Dim EndLine As Integer = 0
    Dim Position As Integer = 0
    Dim Pos As Integer = 0
    Dim Index As Integer = 0

    For i = 0 To RichTextBox1.Lines.Length - 1
        Position += RichTextBox1.Lines(i).Length
        If StartSelection <= Position Then
            StartLine = i
            Exit For
        End If
    Next
    Position = 0
    For i = 0 To RichTextBox1.Lines.Length - 1
        Position += RichTextBox1.Lines(i).Length
        If Position >= EndSelection Then
            EndLine = i
            Exit For
        End If
    Next
    If EndLine = 0 Then
        EndLine = RichTextBox1.Lines.Length - 1
    Else
        EndLine -= 1
    End If
    If Not StartLine = EndLine Then
        Do
            Pos += RichTextBox1.Lines(Index).Length

            If Index = StartLine Then
                Exit Do
            Else
                Index += 1
            End If
        Loop
        Pos -= RichTextBox1.Lines(Index).Length
        For i = StartLine To EndLine - 1
            If i = StartLine Then
                RichTextBox1.Text = RichTextBox1.Text.Remove(Pos + RichTextBox1.Lines(Index).Length + i, 1).Insert(Pos + RichTextBox1.Lines(Index).Length + i, " - ")
                RichTextBox1.Refresh()
            Else
                RichTextBox1.Text = RichTextBox1.Text.Remove(Pos + RichTextBox1.Lines(Index).Length + StartLine, 1).Insert(Pos + RichTextBox1.Lines(Index).Length + StartLine, " - ")
                RichTextBox1.Refresh()
            End If
        Next
    End If

我建议将代码放在文本框或 RichTextbox 的鼠标弹起事件中。

同时使用 string.Join() and LINQ's Aggregate() methods, to fill a StringBuilder 作为文本行的 累加器 的示例。
StringBuilder 对象在处理字符串时是一个方便的存储,它可以限制使用后需要垃圾回收的字符串的数量。

LINQ的Skip() and Take()方法也用于跳过集合中指定数量的元素和指定数量的元素元素。
请注意 Take() 不会溢出:如果要获取的元素数量多于可用元素的数量,它只会获取它能找到的元素。

我混合了 string.Join()Aggregate() 来展示它们的用途,您实际上可以使用一个或另一个来执行所有操作。

使用 Aggregate(),StringBuilder 中的最后一个字符由 Environment.NewLine 确定,需要删除。
请注意,StringBuilder.ToString() 方法允许生成内容的子字符串。
如果您改用 String.Join(),则无需去除尾随字符。

您可以调用 MergeLines() 方法:

RichTextBox1.Text = MergeLines(RichTextBox1.Text, 1, 4)

合并 RichTextBox 中的 4 行文本,从第 1 行到第 4 行。
如果你有 6 行并且你想全部合并,那么指定:

RichTextBox1.Text = MergeLines(RichTextBox1.Text, 0, 5)

该方法检查起始行和结束行是否指定了与文本内容兼容的表达行值。

Imports System.Linq
Imports System.Text

Private Function MergeLines(text As String, lineStart As Integer, lineEnd As Integer) As String
    Dim lines = text.Split(ControlChars.Lf)
    If lines.Length < 2 OrElse (lineStart < 0 OrElse lineEnd >= lines.Length) Then Return text

    Dim sb = lines.Take(lineStart).
        Aggregate(New StringBuilder(), Function(s, ln) s.AppendLine(ln))
    sb.AppendLine(String.Join(" - ", lines.Skip(lineStart).Take(lineEnd - lineStart + 1)))
    lines.Skip(lineEnd + 1).Aggregate(sb, Function(s, ln) s.AppendLine(ln))
    Return sb.ToString(0, sb.Length - Environment.NewLine.Length)
End Function

将字符串元素聚合到 StringBuilder 的第一行代码说明:

Dim sb = lines.
    Take(lineStart).
    Aggregate(New StringBuilder(), 
        Function(s, ln) s.AppendLine(ln)
  • 使用 lines 集合:
    • lineStart行。 lineStart 是要合并的第一行:如果 lineStart = 2 - 第三行 - 然后取 2 行,即行 01).
    • 在新的 StringBuilder 对象中聚合每行。 StringBuilder 附加每一行加上 Environment.NewLine.
  • 聚合的结果是一个填充的 StringBuilder 对象。

C# 版本:

private string MergeLines(string text, int start, int end)
{
    var lines = text.Split('\n'); ;
    if (lines.Length < 2 || (start < 0 || end >= lines.Length)) return text;

    var sb = lines.Take(start).Aggregate(new StringBuilder(), (s, ln) => s.AppendLine(ln));
    sb.AppendLine(string.Join(" - ", lines.Skip(start).Take(end - start + 1)));
    lines.Skip(end + 1).Aggregate(sb, (s, ln) => s.AppendLine(ln));
    return sb.ToString(0, sb.Length - Environment.NewLine.Length);
}