如何从Swift中的字符串中删除空格?

时间:2017-10-02 20:02:04

标签: swift string

我需要删除标点字符周围的前导和尾随空格。

例如:Hello , World ... I 'm a newbie iOS Developer.

我想拥有:> Hello, World... I'm a newbie iOS Developer.

我该怎么做?我试图获取字符串的组成部分并按句子枚举它。但这不是我需要的

8 个答案:

答案 0 :(得分:4)

Rob的答案很棒,但你可以利用\p{Po}正则表达式类来减少它。摆脱标点符号周围的空格然后成为单个正则表达式替换:

import Foundation

let input = "Hello ,  World ... I 'm a newbie iOS Developer."
let result = input.replacingOccurrences(of: "\\s*(\\p{Po}\\s?)\\s*",
                                        with: "$1",
                                        options: [.regularExpression])
print(result) // "Hello, World... I'm a newbie iOS Developer."

Rob的回答也试图修剪前导/尾随空格,但你的输入没有任何一个。如果您关心这一点,可以在结果上致电result.trimmingCharacters(in: .whitespacesAndNewlines)

这是正则表达式的解释。删除双逃逸它看起来像

\s*(\p{Po}\s?)\s*

这包含以下组件:

  • \s* - 匹配零个或多个空白字符(然后扔掉)
  • (…) - 捕获小组。替换保留此组内的任何内容(替换中的$1指的是此组)。
    • \p{Po} - 匹配" Other_Punctuation"中的单个字符unicode类别。其中包括.'等内容,但不包括(-等内容。
    • \s? - 匹配单个可选的空白字符。这会在句点(或省略号)之后保留空格。
  • \s* - 再一次,匹配零个或多个空格字符(然后扔掉)。这就是将, World转换为, World
  • 的原因

答案 1 :(得分:4)

对于Swift 3或4,您可以使用:

let trimmedString = string.trimmingCharacters(in: .whitespaces)

答案 2 :(得分:3)

这是一个非常奇妙的问题,也是一个耻辱,今天在Swift中做起来并不容易(有一天会有,但不是今天)。

我有点讨厌这个代码,但是我在飞机上上了20个小时,没有时间让它更好。这可能至少让您开始使用NSMutableString。在String工作会很好,而Swift讨厌正则表达式,所以这有点可怕,但至少它是一个开始。

import Foundation

let input = "Hello,  World ... I 'm a newbie iOS Developer."

let adjustments = [
    (pattern: "\\s*(\\.\\.\\.|\\.|,)\\s*", replacement: "$1 "), // elipsis or period or comma has trailing space
    (pattern: "\\s*'\\s*", replacement: "'"), // apostrophe has no extra space
    (pattern: "^\\s+|\\s+$", replacement: ""), // remove leading or trailing space
]

let mutableString = NSMutableString(string: input)

for (pattern, replacement) in adjustments {
    let re = try! NSRegularExpression(pattern: pattern)
    re.replaceMatches(in: mutableString,
                      options: [],
                      range: NSRange(location: 0, length: mutableString.length),
                      withTemplate: replacement)
}
mutableString // "Hello, World... I'm a newbie iOS Developer."

当您第一次遇到正则表达式时,它们会非常混乱。阅读这些内容的一些提示:

  • 基金会使用的特定语言由ICU描述。

  • 反斜杠(\)表示正则表达式的“下一个字符是特殊的”。但是在Swift字符串中,反斜杠意味着字符串的“下一个字符是特殊的”。所以你必须把它们加倍。

  • \ s表示“空白字符”

  • \ s *表示“零个或多个空白字符”

  • \ s +表示“一个或多个空白字符”

  • $ 1表示“我们在括号中匹配的东西”

  • |表示“或”

  • ^表示“字符串开头”

  • $表示“字符串结束”

  • 。表示“任何字符”,意思是“实际点”,您必须键入“\\”。在Swift字符串中。

请注意,我检查“...”和“。”在同一个正则表达式中。你必须做那样的事情,否则就是“。”将在“......”内匹配三次。另一种方法是首先用“......”替换“...”(单个省略号字符,通过按Opt-键在Mac上键入)。然后“......”是一个单字符的标点符号。 (您还可以决定在流程结束时将所有省略号重新展开回dot-dot-dot。)

这样的事情可能就是我在现实生活中如何做到这一点,把它完成并运送出去,但是尝试将其构建为逐个字符的状态机可能是值得的。一次一个角色,并跟踪你当前的状态。

答案 3 :(得分:0)

你可以尝试类似的东西 每个标点符号的string.replacingOccurrences(of:",",with:",")...

答案 4 :(得分:0)

在我的手机上没有电脑给你写样本,但如果它总是一个自然的语言字符串,特别是如果你需要支持英语以外的语言,你可以看一下有标点符号和空格的NSLinguisticTagger标签

简介:http://nshipster.com/nslinguistictagger/

文档:https://developer.apple.com/documentation/foundation/nslinguistictagger

答案 5 :(得分:0)

有趣的问题;这是我对非正则表达方式的尝试:

func correct(input: String) -> String {
    typealias Correction = (punctuation: String, replacement: String)

    let corrections: [Correction] = [
        (punctuation: "...", replacement: "... "),
        (punctuation: "'", replacement: "'"),
        (punctuation: ",", replacement: ", "),
    ]

    var transformed = input
    for correction in corrections {
        transformed = transformed
            .components(separatedBy: correction.punctuation)
            .map({ $0.trimmingCharacters(in: .whitespaces) })
            .joined(separator: correction.replacement)
    }

    return transformed
}

let testInput = "Hello , World ... I 'm a newbie iOS Developer."
let testOutput = correct(input: testInput)

// Hello, World... I'm a newbie iOS Developer.

答案 6 :(得分:0)

如果您通过处理字符数组手动执行此操作,则只需要检查空格周围的上一个和下一个字符。使用zip,filter和map的函数式编程可以获得相同的结果:

let testInput = "Hello , World ... I 'm a newbie iOS Developer."

let punctuation    = Set(".\',")
let previousNext   = zip( [" "] + testInput, String(testInput.dropFirst()) + [" "] )
let filteredChars  = zip(Array(previousNext),testInput)
                    .filter{  $1 != " "
                              || !($0.0 != " " && punctuation.contains($0.1))
                           }
let filteredInput = String(filteredChars.map{$1})

print(testInput)     // Hello , World ... I 'm a newbie iOS Developer.
print(filteredInput) // Hello, World... I'm a newbie iOS Developer.

答案 7 :(得分:-1)

快速4、4.2和5

let str = "  Akbar Code  "
let trimmedString = str.trimmingCharacters(in: .whitespaces)