我需要删除标点字符周围的前导和尾随空格。
例如:Hello , World ... I 'm a newbie iOS Developer.
我想拥有:> Hello, World... I'm a newbie iOS Developer.
我该怎么做?我试图获取字符串的组成部分并按句子枚举它。但这不是我需要的
答案 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)