Regex Swift:正则表达式捕获数的数学运算
我喜欢用正则表达式将“我跑12英里”改为“我跑24英里”。“12”可以是任何数字。我使用函数“replace2()”进行数学运算。传递给函数replace2(“$1”)的捕获参数“$1”没有问题。请帮忙Regex Swift:正则表达式捕获数的数学运算,regex,swift,capture,Regex,Swift,Capture,我喜欢用正则表达式将“我跑12英里”改为“我跑24英里”。“12”可以是任何数字。我使用函数“replace2()”进行数学运算。传递给函数replace2(“$1”)的捕获参数“$1”没有问题。请帮忙 func replace( str:String, pattern : String, repl:String)->String?{ let regex = NSRegularExpression .regularExpressionWithPattern(pattern, opt
func replace( str:String, pattern : String, repl:String)->String?{
let regex = NSRegularExpression .regularExpressionWithPattern(pattern, options: nil,error: nil)
let replacedString = regex.stringByReplacingMatchesInString( str, options: nil,
range: NSMakeRange(0, countElements( str)), withTemplate: repl )
return replacedString
}
replace( "I run 12 miles and walk 12.45 km","\\d+(.\\d+)?", "-")!
func replace2(x: String)->String {
let xx = x.toInt()! * 2 // error : return nil?
return String(format: "\(xx)")
}
replace( "I run 12 miles ","(\\d+)", replace2("$1") )! // error
在操场上试试这个:
let str1: NSString = "I run 12 miles"
let str2 = "I run 12 miles"
let match = str1.rangeOfString("\\d+", options: .RegularExpressionSearch)
let finalStr = str1.substringWithRange(match).toInt()
let n: Double = 2.2*Double(finalStr!)
let newStr = str2.stringByReplacingOccurrencesOfString("\\d+", withString: "\(n)", options: NSStringCompareOptions.RegularExpressionSearch, range: nil)
println(newStr) //I run 26.4 miles
//or more simply
let newStr2 = "I run \(n) kilometers"
//yes, I know my conversion is off
如果要动态捕获值并基于捕获的值替换它们,则必须使用
EnumerateMatchesInstalling
。然后,您可以编写一个执行替换的循环:
func stringWithDoubleNumbers(string: String) -> String {
// build array of ranges that need replacing
var ranges = [NSRange]()
let regex = NSRegularExpression(pattern: "[\\d.]+", options: nil, error: nil) as NSRegularExpression
regex.enumerateMatchesInString(string, options: nil, range: NSMakeRange(0, countElements(string))) {
match, flags, stop in
ranges.append(match.range)
}
var doubledString = NSMutableString(string: string)
// iterate backwards so that location is valid despite other replacements
for range in reverse(ranges) {
let foundString = doubledString.substringWithRange(range)
if let value = foundString.toInt() {
let numericString = "\(value * 2)"
doubledString.replaceCharactersInRange(range, withString: numericString)
} else {
let value = NSString(string: foundString).doubleValue
let numericString = "\(value * 2.0)"
doubledString.replaceCharactersInRange(range, withString: numericString)
}
}
return doubledString
}
我做了一些额外的逻辑来处理与浮点类型不同的整数值,但如果您不想担心这种复杂性,可以简化它。//我用上面的Steve和Rob代码进行了实验,我想我可以得到代码来解决简单字符串的问题。我仍然有复杂字符串的问题。我试着解析一个数据记录,它包含多个(-20)数字,或者是整数或者是双精度数字,而不是像在一个例程中处理str2和str3那样的任何序列。不管怎样,多亏了史蒂夫和罗伯
let str2 = "I run 89 miles and 28.576 km"
let str3 = "I run 89.45 miles and 34 km in 34F degree"
var re = NSRegularExpression(pattern: "(\\d+).* (\\d+\\.\\d+)", options: nil, error: nil)
var match = re.firstMatchInString(str2, options: nil, range: NSMakeRange(0, countElements(str2)))
var startIndex = advance(str2.startIndex, match.rangeAtIndex(1).location)
var endIndex = advance(str2.startIndex, match.rangeAtIndex(1).location + match.rangeAtIndex(1).length)
let x1 = str2.substringWithRange(Range(start: startIndex, end: endIndex)).toInt()!
x1
//“我跑了178英里57.152公里”谢谢。这很有效。但我尝试乘以许多(未知)数字,如“我在-34F度下跑了34英里10.54公里。”我喜欢将所有3个数字乘以2。非常感谢。这很有效。但我试着使用纯Swift并试图避开“NS”“除了多余的东西外,还要尽可能多的东西。你能将字符串“我在-34F度下跑34英里和10.54公里”中的所有数字加倍为“我在-68F度下跑68英里和21.08公里”吗。在Perl中,它很简单:“s/(\d+(\。\d+)/$1*2/ge”,如果您愿意,我可以执行swift函数。再长一点,好极了!非常感谢。
startIndex = advance(str2.startIndex, match.rangeAtIndex(2).location)
endIndex = advance(str2.startIndex, match.rangeAtIndex(2).location + match.rangeAtIndex(2).length)
let x2 = str2.substringWithRange(Range(start: startIndex, end: endIndex))
let x2x = NSString(string: x2).doubleValue
let n1 = x1 * 2
let n2: Double = 2.0 * x2x
str2.stringByReplacingOccurrencesOfString("(\\d+)(.* )(\\d+\\.\\d+)", withString: "\(n1)$2\(n2)", options: NSStringCompareOptions.RegularExpressionSearch, range: nil)