首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Regex表达式拆分字符串

如何使用Regex表达式拆分字符串
EN

Stack Overflow用户
提问于 2017-02-27 01:24:16
回答 4查看 13.1K关注 0票数 12

我有一个字符串"323 ECO Economics Course 451 ENG English Course 789 Mathematical Topography",我想使用regex表达式[0-9][0-9][0-9][A-Z][A-Z][A-Z]来拆分这个字符串,以便函数返回数组:

代码语言:javascript
复制
Array = 
["323 ECO Economics Course ", "451 ENG English Course",  "789 Mathematical Topography"]

我怎么用斯威夫特来做这件事呢?

编辑我的问题与链接的问题不同。我意识到可以使用myString.components(separatedBy: "splitting string")快速拆分字符串,问题是这个问题不能解决如何使splitting string成为正则表达式。我试过使用mystring.components(separatedBy: "[0-9][0-9][0-9][A-Z][A-Z][A-Z]", options: .regularExpression),但这不起作用。

如何使separatedBy:部分成为正则表达式?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-02-27 02:07:37

Swift到目前为止还没有本机正则表达式。但是Foundation提供了NSRegularExpression

代码语言:javascript
复制
import Foundation

let toSearch = "323 ECO Economics Course 451 ENG English Course 789 MAT Mathematical Topography"

let pattern = "[0-9]{3} [A-Z]{3}"
let regex = try! NSRegularExpression(pattern: pattern, options: [])

// NSRegularExpression works with objective-c NSString, which are utf16 encoded
let matches = regex.matches(in: toSearch, range: NSMakeRange(0, toSearch.utf16.count))

// the combination of zip, dropFirst and map to optional here is a trick
// to be able to map on [(result1, result2), (result2, result3), (result3, nil)]
let results = zip(matches, matches.dropFirst().map { Optional.some($0) } + [nil]).map { current, next -> String in
  let range = current.rangeAt(0)
  let start = String.UTF16Index(range.location)
  // if there's a next, use it's starting location as the ending of our match
  // otherwise, go to the end of the searched string
  let end = next.map { $0.rangeAt(0) }.map { String.UTF16Index($0.location) } ?? String.UTF16Index(toSearch.utf16.count)

  return String(toSearch.utf16[start..<end])!
}

dump(results)

运行这将输出

代码语言:javascript
复制
▿ 3 elements
  - "323 ECO Economics Course "
  - "451 ENG English Course "
  - "789 MAT Mathematical Topography"
票数 5
EN

Stack Overflow用户

发布于 2017-02-27 01:57:47

您可以使用regex "\\b[0-9]{1,}[a-zA-Z ]{1,}"和来自answer的这个扩展来使用文字、caseInsensitive或regularExpression搜索获取字符串的所有范围:

代码语言:javascript
复制
extension StringProtocol {
    func ranges<S: StringProtocol>(of string: S, options: String.CompareOptions = []) -> [Range<Index>] {
        var result: [Range<Index>] = []
        var startIndex = self.startIndex
        while startIndex < endIndex,
            let range = self[startIndex...].range(of: string, options: options) {
                result.append(range)
                startIndex = range.lowerBound < range.upperBound ? range.upperBound :
                    index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        }
        return result
    }
}
代码语言:javascript
复制
let inputString = "323 ECO Economics Course 451 ENG English Course 789 Mathematical Topography"

let courses = inputString.ranges(of: "\\b[0-9]{1,}[a-zA-Z ]{1,}", options: .regularExpression).map { inputString[$0].trimmingCharacters(in: .whitespaces) }

print(courses)   //   ["323 ECO Economics Course", "451 ENG English Course", "789 Mathematical Topography"]
票数 12
EN

Stack Overflow用户

发布于 2021-03-21 22:43:43

我需要这样的东西,并且应该更像JS String.prototype.split(pat: RegExp)或Rust's String.splitn(pat: String.splitn<‘a>),但是使用Regex。

代码语言:javascript
复制
extension NSRegularExpression {
    convenience init(_ pattern: String) {...}
    
    
    /// An array of substring of the given string, separated by this regular expression, restricted to returning at most n items.
    /// If n substrings are returned, the last substring (the nth substring) will contain the remainder of the string.
    /// - Parameter str: String to be matched
    /// - Parameter n: If `n` is specified and n != -1, it will be split into n elements else split into all occurences of this pattern
    func splitn(_ str: String, _ n: Int = -1) -> [String] {
        let range = NSRange(location: 0, length: str.utf8.count)
        let matches = self.matches(in: str, range: range);
        
        var result = [String]()
        if (n != -1 && n < 2) || matches.isEmpty  { return [str] }
        
        if let first = matches.first?.range {
            if first.location == 0 { result.append("") }
            if first.location != 0 {
                let _range = NSRange(location: 0, length: first.location)
                result.append(String(str[Range(_range, in: str)!]))
            }
        }
        
        for (cur, next) in zip(matches, matches[1...]) {
            let loc = cur.range.location + cur.range.length
            if n != -1 && result.count + 1 == n {
                let _range = NSRange(location: loc, length: str.utf8.count - loc)
                result.append(String(str[Range(_range, in: str)!]))
                return result
                
            }
            let len = next.range.location - loc
            let _range = NSRange(location: loc, length: len)
            result.append(String(str[Range(_range, in: str)!]))
        }
        
        if let last = matches.last?.range, !(n != -1 && result.count >= n) {
            let lastIndex = last.length + last.location
            if lastIndex == str.utf8.count { result.append("") }
            if lastIndex < str.utf8.count {
                let _range = NSRange(location: lastIndex, length: str.utf8.count - lastIndex)
                result.append(String(str[Range(_range, in: str)!]))
            }
        }
        
        return result;
    }
    
}

通过下列测试

代码语言:javascript
复制
func testRegexSplit() {
        XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn("My . Love"), ["My", "Love"])
        XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn("My . Love . "), ["My", "Love", ""])
        XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn(" . My . Love"), ["", "My", "Love"])
        XCTAssertEqual(NSRegularExpression("\\s*[.]\\s+").splitn(" . My . Love . "), ["", "My", "Love", ""])
        XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX"), ["", "My", "", "Love", ""])
    }



func testRegexSplitWithN() {
        XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 1), ["xXMyxXxXLovexX"])
        XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", -1), ["", "My", "", "Love", ""])
        XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 2), ["", "MyxXxXLovexX"])
        XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 3), ["", "My", "xXLovexX"])
        XCTAssertEqual(NSRegularExpression("xX").splitn("xXMyxXxXLovexX", 4), ["", "My", "", "LovexX"])
    }

func testNoMatches() {
        XCTAssertEqual(NSRegularExpression("xX").splitn("MyLove", 1), ["MyLove"])
        XCTAssertEqual(NSRegularExpression("xX").splitn("MyLove"), ["MyLove"])
        XCTAssertEqual(NSRegularExpression("xX").splitn("MyLove", 3), ["MyLove"])
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42476395

复制
相关文章

相似问题

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