Swift 4.4
我想使用NSAttributedString创建NSRegularExpression
~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~像这样,

我可以创建和分配属性,但问题是我不知道如何使用NSRegularExpression,但我在雷恩德利希文章的帮助下尝试了许多逻辑。
我试过的一些逻辑。
(1) "(^|\\s|\\b)*(\\S).*(\\S)*($|\\s|\\b)"
(2) "(\\~(.*?)\\~)"
(3) "\\sand\\b"
(4) "(?:^|\\s|$)#[\\p{L}0-9_]*"
(5) "(?:^\\s+)|(?:\\s+$)"我只需要一种模式的bold 或 italic 或 strikethrough
更新
案例1:
let string = "~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~"
let pattern = "((^|)~(.*?)(\\S+)~($|\\s))"产量如下,
Pattern: ((^|)~(.*?)(\S+)~($|\s))
~This two~
~strikethrough~
~abc~案例2:
let string = "~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~"
let pattern = "((^|)~(.?)(\\S+)~($|\\s))" //here '*' removed产量如下,
Pattern: ((^|)~(.?)(\S+)~($|\s))
~strikethrough~
~abc~提前谢谢。
更新2
我找到了答案
发布于 2019-01-10 09:55:16
我无法将模式组合成一个或(|),并使它们正确匹配,但是如果我一个接一个地匹配它们,它就会工作。
let string = "~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~"
let textPattern = "[:alpha:][:punct:][:space:]"
let range = NSRange(location: 0, length: string.utf16.count)
let patterns:[String] = ["(?:~([\(textPattern)]*)~)", "(?:\\*([\(textPattern)]*)\\*)", "(?:<([\(textPattern)]*)>)", "(?:_([\(textPattern)]*)_)"]
for pattern in patterns {
let regex = try! NSRegularExpression(pattern: pattern)
regex.enumerateMatches(in: string, range: range, using: { (result, flag, pointer) in
if let result = result {
for i in 1..<result.numberOfRanges {
let srange = Range(result.range(at: i))!
let start = String.Index(encodedOffset: srange.lowerBound)
let end = String.Index(encodedOffset: srange.upperBound)
let substr = String(string[start..<end])
print("\(result.range(at: i)) => \(substr)")
}
}
})
}输出
{1,8} =>这两个 {58,13} =>划线 {95,3} => abc {16,9} =>粗体文本 {42,9} =>文本颜色 {78,14} =>斜体(字*)
更新:将我的模式更改为不包括格式字符、~、*等,并在示例中改进输出,以更清楚地显示匹配的正确数量和匹配的内容。
发布于 2019-01-10 11:01:00
这一守则应适用于:
let string = "~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~"
let embedded = ".*?"
let strikeThroughGroupName = "strikethroughGroupName"
let boldGroupName = "boldGroupName"
let colorGroupName = "colorGroupName"
let italicGroupName = "italicGroupName"
let groupNames = [strikeThroughGroupName, boldGroupName, italicGroupName, colorGroupName]
let pattern = "(~(?<\(strikeThroughGroupName)>\(embedded))~)|(<(?<\(colorGroupName)>\(embedded))>)|(_(?<\(italicGroupName)>\(embedded))_)|(\\*(?<\(boldGroupName)>\(embedded))\\*)"
print("Pattern: \(pattern)")
do {
let regex = try NSRegularExpression(pattern: pattern, options: [])
let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
matches.forEach { (aMatch) in
if let groupFound = groupNames.first(where: { aMatch.range(withName: $0).location != NSNotFound }),
let range = Range(aMatch.range(withName: groupFound), in: string) {
let textFound = string[range]
print("Found: \(textFound) with effect: \(groupFound) at NSRange: \(aMatch.range(withName: groupFound))")
}
let fullNSRange = aMatch.range
if let fullRange = Range(fullNSRange, in: string) {
let textFound = string[fullRange]
print("Full Text Found: \(textFound)")
}
}
} catch {
print("Regex error: \(error)")
}输出:
$>Pattern: (~(?<strikethroughGroupName>.*?)~)|(<(?<colorGroupName>.*?)>)|(_(?<italicGroupName>.*?)_)|(\*(?<boldGroupName>.*?)\*)
$>Found: This two with effect: strikethroughGroupName at NSRange: {1, 8}
$>Full Text Found: ~This two~
$>Found: bold text with effect: boldGroupName at NSRange: {16, 9}
$>Full Text Found: *bold text*
$>Found: strikethrough with effect: strikethroughGroupName at NSRange: {59, 13}
$>Full Text Found: ~strikethrough~
$>Found: italic (word*) with effect: italicGroupName at NSRange: {79, 14}
$>Full Text Found: _italic (word*)_
$>Found: abc with effect: strikethroughGroupName at NSRange: {96, 3}
$>Full Text Found: ~abc~边注:
·我使用了组名(可用于regex)。
它的结构是(?<groupName>groupToCapture)。
·我使用embedded作为快速测试工具。它不可能涵盖所有的案件。例如,它没有涵盖string中行的更改情况。如果它是<text\ncolor> (有一个断线),它将不匹配。在那里,如果需要,可以使用希望包含断线的正则表达式。
发布于 2019-01-12 07:06:42
我为我自己的问题找到了一个答案,我会用一个例子来解释它,这样你就可以自己尝试了。
在这里,
//Some randome bunch of words
let string = "1. *うちに* comes from the ~kanji~ *内* which mean “inside” or “within” and has _two distinct_ meanings in Japanese. 2. Firstly, it shows that something happens within ~a~ period of time. “While” something is happening, you do an action.~Very minimal as~ far as features tha *t* are supported in the Web version. It works in a pinch, if you’re in a hurry and ne. Nice~"
//to find words which are suppose to be stricked using '~' character
let pattern = "~[^\\s](.*?[^\\s])??~"
let regex = try! NSRegularExpression(pattern: pattern, options: [])
let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count))
matches.forEach { (aMatch) in
let matchedRange = aMatch.range(at: 0)
let matchingText = (string as NSString).substring(with: matchedRange)
print(matchingText)
}非常感谢
https://stackoverflow.com/questions/54124406
复制相似问题