Swift正则表达式与变量(非固定)字符串子组件

huangapple go评论70阅读模式
英文:

Swift Regex with variable (not fixed) String subcomponent

问题

在Swift 5.8+中,是否可以创建一个可重复使用的Regex模式,其中包含一个可变(非固定)的组件?如果是,如何实现?

从概念上看,考虑一个关键词变量将作为正则表达式的一部分的用例。这将类似于String类型中的插值。

func example(keyword: String) {
    // 非功能概念简写
    var regex = /…\(keyword)/
    // 对regex执行某些操作
}

很可能/…/正则表达式字面量不支持这种方法。而且,\(...)字符串插值语法与正则表达式的(…)捕获语法可能存在相似性问题。

相反,是否可以使用一些较新的(非NSRegularExpression)正则表达式定义方法中的任何一种,以某种方式支持可变的String子组件?

英文:

Is it possible to create a reuseable Swift 5.8+ Regex pattern with a variable (not-fixed) component? If yes, how?

Conceptually, consider the use case where a keyword variable is to be used as part of the regex. This would be an analog to interpolations in the String type.

func example(keyword: String) {
    // non-functional concept shorthand
    var regex = /…\(keyword)/
    // do something with regex 
}

It's likely that a /…/ regex literal does not have a syntax which supports this approach. And, there may be issues with similarity of the \(…) String interpolation syntax the regex (…) capture syntax.

Rather, can any of the several newer (non-NSRegularExpression) regex definition approaches be used in some way to support a variable String sub-component?

答案1

得分: 5

RegexBuilder 提供了一种方便的方式来构建正则表达式。例如:

import RegexBuilder

let string = "prefixandthissuffix"

func example(keyword: String) {
    // non-functional concept shorthand
    var regex = Regex {
        "prefix"
        keyword
        "suffix"
    }

    if let match = string.wholeMatch(of: regex) {
        print(match.output)
    } else {
        print("\(keyword): nomatch")
    }
}

example(keyword: "andthis")  // 输出匹配
example(keyword: "andthat")  // 输出nomatch

请注意,每次关键字字符串需要更改时,需要重新构建 Regex。动态重新构建可以封装在一个函数中。

func quotedRegex(keyword: String) -> Regex<Substring> {
    let regex = Regex {
        /"/
        keyword
        /"/
    }
    return regex
}

let string = "{\"key1\":\"value\"}"
for word in ["key1", "KEY1", "key2"] {
    var regex = quotedRegex(keyword: word)
    regex = regex.ignoresCase() // 转换后
    if let match = string.firstMatch(of: regex) {
        print("\(word) matched \(match.output)")
    } else {
        print("\(word) not matched")
    }
}

// 输出:
//   key1 matched "key1"
//   KEY1 matched "key1"
//   key2 not matched
英文:

RegexBuilder provides a convenient way to build this. For example:

import RegexBuilder

let string = &quot;prefixandthissuffix&quot;

func example(keyword: String) {
    // non-functional concept shorthand
    var regex = Regex {
        &quot;prefix&quot;
        keyword
        &quot;suffix&quot;
    }

    if let match = string.wholeMatch(of: regex) {
        print(match.output)
    } else {
        print(&quot;\(keyword): nomatch&quot;)
    }
}

example(keyword: &quot;andthis&quot;)  // prints match
example(keyword: &quot;andthat&quot;)  // nomatch

Note that the Regex needs to be rebuild each time the keyword string needs to change. The dynamic rebuilding can be encapsulated in a function.

func quotedRegex(keyword: String) -&gt; Regex&lt;Substring&gt; {
    let regex = Regex {
        /&quot;/
        keyword
        /&quot;/
    }
    return regex
}

let string = &quot;{\&quot;key1\&quot;:\&quot;value\&quot;}&quot;
for word in [&quot;key1&quot;, &quot;KEY1&quot;, &quot;key2&quot;] {
    var regex = quotedRegex(keyword: word)
    regex = regex.ignoresCase() // transformed
    if let match = string.firstMatch(of: regex) {
        print(&quot;\(word) matched \(match.output)&quot;)
    } else {
        print(&quot;\(word) not matched&quot;)
    }
}

// print:
//   key1 matched &quot;key1&quot;
//   KEY1 matched &quot;key1&quot;
//   key2 not matched

huangapple
  • 本文由 发表于 2023年7月3日 08:42:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76601287.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定