首页 > 解决方案 > replaceOccurrences() 用于通过正则表达式将文本拆分为多行

问题描述

我正在尝试在String.replacingOccurrences(of:with:options:range:)带有正则表达式的搜索/替换界面中使用。这是关键点:让用户自己输入模式。

任何正则表达式模式在“搜索”字段中都可以正常工作。

但是我在替换字段中有一个问题。我当前的程序忽略了新行的模式“\n”。它不是将文本分成几行,而是用字母“n”替换多个点。

我所看到的

我的代码(Xcode 12,Swift 5):

import SwiftUI

struct ContentView: View {
    
    @State private var before: String = "1 Introduction....... 1 1.1 Communicating at a Distance................ 1 1.2 Computers Communicate Differently ................ 4 1.3 Early Wide Area Store-and-Forward Networks......... 5 1.4 Packets and Routers ...................... 6 1.5 Addressing and Packets.................... 7"
    
    @State private var searchString = ""
    @State private var replaceString = ""
    
    private var after: String {
        before.replacingOccurrences(
            of: searchString,
            with: replaceString,
            options: .regularExpression,
            range: .none
        )
    }
    
    var body: some View {
        
        HStack(alignment: .top) {
            
            VStack(alignment: .leading) {
                Text("Before")
                TextEditor(text: $before)
                    .padding(.bottom)
                
                Text("After")
                TextEditor(text: Binding.constant(after))
            }
            .padding()
            
            VStack(alignment: .leading){
                Text("Search")
                TextField("Empty", text: $searchString)
                    .padding(.bottom)
                
                Text("Replace")
                TextField("Empty", text: $replaceString)
            }
            .padding()
        }
        .frame(minWidth: 800, minHeight: 600, alignment: .top)
        .font(Font.system(size: 16))
    }
}

如果我在 Search 字段(运行程序的字段,而不是代码)中输入文本\.+ \d+( )*并在 Replace 字段中输入,\n我希望在 After 字段中看到:

1 Introduction
1.1 Communicating at a Distance
1.2 Computers Communicate Differently 
1.3 Early Wide Area Store-and-Forward Networks
1.4 Packets and Routers 
1.5 Addressing and Packets

但事实上我看到了这个:

1 Introductionn1.1 Communicating at a Distancen1.2 Computers Communicate Differently n1.3 Early Wide Area Store-and-Forward Networksn1.4 Packets and Routers n1.5 Addressing and Packetsn

我哪里错了?

标签: swiftui

解决方案


to make your code work as you would like, ie type \.+ \d+( )* and \n , try this, works for me:

private var after: String {
    before.replacingOccurrences(
        of: searchString,
        with: replaceString.replacingOccurrences(of: "\\n", with: "\n"),
        options: .regularExpression,
        range: .none)
}

EDIT1:

Here is my test code that works for me when I type into the TextFields. I'm using Xcode 13.1 on macos 12.1beta, targeting ios 15 and macCatalyst 12 and macos12 only. Tested on real devices.

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    
    @State private var before: String = "1 Introduction....... 1 1.1 Communicating at a Distance................ 1 1.2 Computers Communicate Differently ................ 4 1.3 Early Wide Area Store-and-Forward Networks......... 5 1.4 Packets and Routers ...................... 6 1.5 Addressing and Packets.................... 7"
    
    @State private var searchString = ""
    @State private var replaceString = ""
    
    private var after: String {
        before.replacingOccurrences(
            of: searchString,
            with: replaceString.replacingOccurrences(of: "\\n", with: "\n"),
            options: .regularExpression,
            range: .none)
    }
    
    var body: some View {
        HStack(alignment: .top) {
            VStack(alignment: .leading) {
                Text("Before")
                TextEditor(text: $before).padding(.bottom)
                Text("After")
                TextEditor(text: Binding.constant(after))
            }.padding()
            VStack(alignment: .leading){
                Text("Search")
                TextField("Empty", text: $searchString).padding(.bottom)
                Text("Replace")
                TextField("Empty", text: $replaceString)
            }.padding()
        }
        .frame(minWidth: 800, minHeight: 600, alignment: .top)
        .font(Font.system(size: 16))
    }
}

推荐阅读