从字符串中删除空格和多行?

4

我有一个字符串,像这样:

"  \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n       tjhfhdf \n      "

I want the result is:

"assddd\nadjffffdd\ntjhfhdf". 

1:我使用了trimmingCharacters方法来移除开头和结尾:

let title = "  \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n       tjhfhdf \n".trimmingCharacters(in: .whitespacesAndNewlines)

2:删除空白字符

let result = title.replacingOccurrences(of: " ", with: "")

但是,如何保留字符与第一个"\n"之间的换行符并删除其他"\n"呢?

let result = title.replacingOccurrences(of: "\n", with: "") - EmilioPelaez
你可以使用正则表达式来完成这个任务。 - Reinier Melian
它将替换它们所有,我想保留第一个。 - Longshihua
我只想保留字符之间的第一个\n。因此,我发布的结果是"assddd\nadjffffdd\ntjhfhdf"。在"d"和"a"之间有一个\n,第二个位置是在"d"和"t"之间。 - Longshihua
7个回答

7

您可以使用正则表达式查找两个或多个连续的换行符,并将它们替换为单个换行符。例如:

let s1 = "AA\n\nBB\nCC\n\n\n\n\nDD"
let s2 = s1.replacingOccurrences(of: "\\n{2,}", with: "\n", options: .regularExpression)

print(s1.debugDescription) // "AA\n\nBB\nCC\n\n\n\n\nDD"
print(s2.debugDescription) // "AA\nBB\nCC\nDD"

适用于您的情况:

let title = "  \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n       tjhfhdf \n      "

let result = title.trimmingCharacters(in: .whitespacesAndNewlines)
    .replacingOccurrences(of: " ", with: "")
    .replacingOccurrences(of: "\\n{2,}", with: "\n", options: .regularExpression)

print(result.debugDescription) // "assddd\nadjffffdd\ntjhfhdf"

3

从你的示例文本开始,我们可以修剪两端:

let sample = "  \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n       tjhfhdf \n      "
let trimmedEnds = sample.trimmingCharacters(in: .whitespacesAndNewlines)

如果您只想删除空格和压缩换行符:

let noHorizSpace = trimmedEnds.replacingOccurrences(of: " ", with: "") // remove all spaces
let singleVertSpace = noHorizSpace.replacingOccurrences(of: "\\n{2,}", with: "\n", options: .regularExpression) // squash runs of two or more newlines

或者使用正则表达式来匹配空格:
let noHorizSpace = trimmedEnds.replacingOccurrences(of: " +", with: "", options: .regularExpression)
let singleVertSpace = noHorizSpace.replacingOccurrences(of: "\\n{2,}", with: "\n", options: .regularExpression)

但是(为了好玩?)所有Unicode水平(空格、制表符等)和垂直(换行符、进纸符、段落分隔符等)的情况怎么办? 对此,有正则表达式模式\h\v

let noHorizSpace = trimmedEnds.replacingOccurrences(of: "\\h+", with: "", options: .regularExpression)
let singleVertSpace = noHorizSpace.replacingOccurrences(of: "\\v+", with: "\n", options: .regularExpression)

您可以使用单个正则表达式解决此问题,但最好遵循ICU RE用户指南中的建议,使用多个更简单的正则表达式。


1
一种可能的解决方案:

let str = "  \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n       tjhfhdf \n      "
print("str: \(str)")
let str2 = str.replacingOccurrences(of: " ", with: "")
print("str2: \(str2)")
let lines = str2.components(separatedBy:"\n")
print("lines: \(lines)")
let linesFiltered = lines.filter({($0.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)).count > 0})
print("linesFiltered: \(linesFiltered)")
let linesTrimmed = linesFiltered.map({$0.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)})
print("linesTrimmed: \(linesTrimmed)")
let endStr = linesTrimmed.joined(separator: "\n")
print("endStr:\n\(endStr)")
print("endStr:\n\(endStr.debugDescription)")

思路:
删除所有空格,因为它们是不需要的。
获取所有由换行符(“\n”)分隔的行,因为你需要重新组装它们,并将重复的行仅保留一行并放入数组中。
删除空行(无论只有空格和/或换行符)
删除每行前后的空格/换行符(修剪)
重新组合字符串

输出结果:

str:   
 assddd




 adjf fff dd 



       tjhfhdf 

str2: 
assddd




adjffffdd



tjhfhdf

lines: ["", "assddd", "", "", "", "", "adjffffdd", "", "", "", "tjhfhdf", ""]
linesFiltered: ["assddd", "adjffffdd", "tjhfhdf"]
linesTrimmed: ["assddd", "adjffffdd", "tjhfhdf"]
endStr:
assddd
adjffffdd
tjhfhdf
endStr:
"assddd\nadjffffdd\ntjhfhdf"

1

正如我在评论中所说,使用正则表达式可以实现这一点,

func stringByAdjustingString(text:String) ->String{
    do{

    let regex = try NSRegularExpression(pattern: "\\n+", options:[.dotMatchesLineSeparators])
    let resultString = regex.stringByReplacingMatches(in: text, range: NSMakeRange(0, text.utf16.count), withTemplate: "\n")

    return resultString.replacingOccurrences(of: " ", with: "").trimmingCharacters(in: .whitespacesAndNewlines)
    }
    catch{
        return ""
    }
}

输入: " \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n tjhfhdf \n "

输出: "assddd\nadjffffdd\ntjhfhdf"


1
你的最后一个返回语句永远不会被执行。NSRegularExpression.MatchingOptions.init(rawValue: 0) 这看起来很丑,为什么不直接用 []?顺便说一下,这是默认值,所以可以省略选项参数。 - Leo Dabus
1
顺便提一下,不必初始化一个新的NSString对象来获取它的长度,你可以直接传递String.UTF16View计数 NSMakeRange(0, text.utf16.count)。请注意,这与MartinR提供的解决方案完全相同,但它还替换了单个换行符的不必要出现。 - Leo Dabus
感谢@LeoDabus根据您的评论和建议更新了我的答案。 - Reinier Melian

1
    It should help you

   var str = "  \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n       tjhfhdf \n      "
        str = str.trimmingCharacters(in: .whitespacesAndNewlines)
        str = str.replacingOccurrences(of: " ", with: "")
        //str = str.replacingOccurrences(of: "\n\n", with: "\n")
        let array = str.components(separatedBy: "\n")
        var finalArray = [String]()
        for x in array {
            if !x.isEmpty  {
                finalArray.append(x)
            }
        }
        str = finalArray.joined(separator: "\n")

1
if x.lengthOfBytes(using: String.Encoding.utf8) > 0 这是一种复杂的检查字符串是否为空的方式...其实有一个 isEmpty 方法! - Martin R
CharacterSet is redundant trimmingCharacters(in: .whitespacesAndNewlines) and better to use newLines character set components(separatedBy: .newLines) - Leo Dabus

0
var titleTrimmedLines = [String]()    
let title = "  \n assddd\n\n\n\n\n adjf fff dd \n\n\n\n       tjhfhdf \n      "
title(separatedBy: CharacterSet.newlines).forEach { titleTrimmedLines.append($0.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)) }
let result = titleTrimmedLines.joined()

-1
您可以使用以下方法去除字符串中的空格:
yourString.trimmingCharacters(in: .whitespaces)

或者如果你想删除空格和行

yourString.trimmingCharacters(in: .whitespacesAndNewlines)

希望它能有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接