我正在寻找一种方法来识别字符模式中的字符模式并删除该模式的任何内部示例(如果存在(,仅保留外部示例。
一个例子是:
str = "some text [outer part [inner part] back to outer part] more text"
我想删除内部模式[ ]
留下:
str = "some text [outer part inner part back to outer part] more text"
这并不总是格式。人们还可以看到:
str = "this text [does does no need inner brackets removed] as there aren't any"
str = "this text [does does not] need inner brackets [removed] as there aren't any"
str = "this text [has one [instance] of inner brackets] and another [that is] okay"
注意:如果打开和关闭分隔符不同是一个问题,我可以将它们更改为一个分隔符,例如 *,但我仍然想摆脱内部分隔符。
这看起来很简单,但事实证明比我预期的要难,因为str_replace不会自然地检测到哪个是外部的,哪个是内部的。例如,在下面我可以找到字符 [ 但不确定如何仅在它位于另一个 [...
let string = "some text [outer part [inner part] back to outer part] more text"
if string.range(of: "[b(?=.*[)[a-zA-Z]{1,8}b", options: [.regularExpression, caseInsensitive]) != nil {
print("found a match")
} else {
print("no match present")
}
感谢您的任何建议。
您可以找到右方括号的第一个索引,然后搜索左方括号的最后一个索引,直到该索引。然后,您可以检查之前和之后的子字符串是否有左括号和右括号:
extension StringProtocol where Self: RangeReplaceableCollection {
mutating func removeInnerBrackets() {
if let close = firstIndex(of: "]"),
let open = self[..<close].lastIndex(of: "["),
let _ = self[..<open].firstIndex(of: "["),
let _ = self[index(after: close)...].firstIndex(of: "]") {
remove(at: close)
remove(at: open)
}
}
}
<小时 />var sentence = "some text [outer [part [inner part] back to outer] part] more text"
sentence.removeInnerBrackets()
sentence // "some text [outer [part inner part back to outer] part] more text"
像这样的事情呢:
func removeInnerDelimiters(S: String) -> String {
var S = S
var lastOpeningCharPos = -1
var closingCharPos = -1
for (index, c) in S.enumerated() {
if c == "[" {
lastOpeningCharPos = index
} else if c == "]" {
closingCharPos = index
break
}
}
if lastOpeningCharPos > -1 && closingCharPos > 0 {
S.remove(at: S.index(S.startIndex, offsetBy: closingCharPos))
S.remove(at: S.index(S.startIndex, offsetBy: lastOpeningCharPos))
}
return S
}
所以基本上你遍历了整个字符串,当你找到第一个]
时,你只需删除你找到的最后[
,当然]