返回正则表达式模式匹配

时间:2016-08-23 21:10:56

标签: swift pattern-matching

我有一个字符串(在本例中为HTML),其中包含用于显示体育比赛结果的相同模式。因此,HTML标记是已知的,但每个游戏的值都不是。

  

在Perl中,我们可以这样做:

if ( $content =~ /\<\/a\>\<br\>(\d+)\<\/span\>\<br\>(\d+)\-(\d+).+\<\/a\>\<br\>(\d+)\<\/span\>\<br\>(\d+)\-(\d+)/) {
  $visitingTeamScore = $1; // $1 is the 1st matched digit
  $visitingTeamWins = $2; // $2 is the 2nd matched digit
  $visitingTeamLosses = $3; // Etc
  $homeTeamScore = $4;
  $homeTeamWins = $5;
  $homeTeamLosses = $6;
}
     

返回括号内的数字,在本例中为6个不同数字长度的整数。然后我们可以将这些匹配分配给变量。

从这个问题的答案:Swift Get string between 2 strings in a string,我有以下Swift代码:

extension String {
    func sliceFrom(start: String, to: String) -> String? {
        return (rangeOfString(start)?.endIndex).flatMap { sInd in
            (rangeOfString(to, range: sInd..<endIndex)?.startIndex).map { eInd in
                substringWithRange(sInd..<eInd)
            }
        }
    }
}

let firstMatch = content?.sliceFrom("</a><br>", to: "</span>") // The first integer in the string

当得到第4个整数也在</a\><br></span>之间时会出现问题,因此结果匹配将再次成为第一个数字。

我可以手动计算字符(这本身并不是一个完美的科学,因为每个整数中的数字可以不同)来做一些丑陋的事情:

let newRawHTML = content![content!.startIndex.advancedBy(15)...content!.startIndex.advancedBy(5)]

另一种可能性是从字符串中删除已经匹配的任何内容,使每次后续搜索都缩短(我不确定如何实现。)这样做的方法是什么?斯威夫特有没有办法“拔出”比赛?

1 个答案:

答案 0 :(得分:2)

您作为Perl示例显示的代码使用正则表达式。 如果模式变得有点复杂,最好直接使用NSRegularExpression

let pattern = "</a><br>(\\d+)</span><br>(\\d+)-(\\d+).+</a><br>(\\d+)</span><br>(\\d+)-(\\d+)"
let regex = try! NSRegularExpression(pattern: pattern, options: [])
if let match = regex.firstMatchInString(content, options: [], range: NSRange(0..<content.utf16.count)) {
    let visitingTeamScore = (content as NSString).substringWithRange(match.rangeAtIndex(1))
    let visitingTeamWins = (content as NSString).substringWithRange(match.rangeAtIndex(2))
    let visitingTeamLosses = (content as NSString).substringWithRange(match.rangeAtIndex(3))
    let homeTeamScore = (content as NSString).substringWithRange(match.rangeAtIndex(4))
    let homeTeamWins = (content as NSString).substringWithRange(match.rangeAtIndex(5))
    let homeTeamLosses = (content as NSString).substringWithRange(match.rangeAtIndex(6))
    //...use the values
}
相关问题