首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建使用NSRegularExpression的模式

创建使用NSRegularExpression的模式
EN

Stack Overflow用户
提问于 2019-01-10 08:18:00
回答 3查看 712关注 0票数 2

Swift 4.4

我想使用NSAttributedString创建NSRegularExpression

代码语言:javascript
复制
~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~

像这样,

我可以创建和分配属性,但问题是我不知道如何使用NSRegularExpression,但我在雷恩德利希文章的帮助下尝试了许多逻辑。

我试过的一些逻辑。

代码语言:javascript
复制
(1) "(^|\\s|\\b)*(\\S).*(\\S)*($|\\s|\\b)"
(2) "(\\~(.*?)\\~)"
(3) "\\sand\\b"
(4) "(?:^|\\s|$)#[\\p{L}0-9_]*"
(5) "(?:^\\s+)|(?:\\s+$)"

我只需要一种模式的bold italic strikethrough

更新

案例1:

代码语言:javascript
复制
let string = "~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~"
let pattern = "((^|)~(.*?)(\\S+)~($|\\s))"

产量如下,

代码语言:javascript
复制
Pattern: ((^|)~(.*?)(\S+)~($|\s))
~This two~ 
~strikethrough~ 
~abc~

案例2:

代码语言:javascript
复制
let string = "~This two~ are *bold text* and different <textcolor> and ~strikethrough~ and _italic (word*)_ ~abc~"
let pattern = "((^|)~(.?)(\\S+)~($|\\s))" //here '*' removed

产量如下,

代码语言:javascript
复制
Pattern: ((^|)~(.?)(\S+)~($|\s))
~strikethrough~ 
~abc~

提前谢谢。

更新2

我找到了答案

EN

回答 3

Stack Overflow用户

发布于 2019-01-10 09:55:16

我无法将模式组合成一个或(|),并使它们正确匹配,但是如果我一个接一个地匹配它们,它就会工作。

代码语言:javascript
复制
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} =>斜体(字*)

更新:将我的模式更改为不包括格式字符、~、*等,并在示例中改进输出,以更清楚地显示匹配的正确数量和匹配的内容。

票数 3
EN

Stack Overflow用户

发布于 2019-01-10 11:01:00

这一守则应适用于:

代码语言:javascript
复制
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)")
}

输出:

代码语言:javascript
复制
$>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> (有一个断线),它将不匹配。在那里,如果需要,可以使用希望包含断线的正则表达式。

票数 3
EN

Stack Overflow用户

发布于 2019-01-12 07:06:42

我为我自己的问题找到了一个答案,我会用一个例子来解释它,这样你就可以自己尝试了。

在这里,

代码语言:javascript
复制
    //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)
}

非常感谢

,(1) 莱姆 (2) 乔基姆·丹尼尔森 (3) 编码列车

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54124406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档