使用Swift随机替换

Dan*_*iel 2 random replace swift

我遇到了一个问题,我不知道如何解决,我希望有人能帮助我.目前我有一个字符串变量,后来我用下划线替换字符串中的字母,如下所示:

var str = "Hello playground"

let replace = str.replacingOccurrences(of: "\\S", with: "_", options: .regularExpression)

print(str)
Run Code Online (Sandbox Code Playgroud)

知道我想在str中随机生成25%的字符(在这种情况下为16*0,25 = 4),所以后来打印出类似这些例子的内容:

str = "H__l_ ___yg_____"

str = "_____ play______"

str = "__ll_ ____g____d"
Run Code Online (Sandbox Code Playgroud)

有没有人有任何想法如何做到这一点?

Lar*_*rme 5

可能的解决方案:

var str = "Hello playground"
print("Before: \(str)")
do {
    let regex = try NSRegularExpression(pattern: "\\S", options: [])
    let matches = regex.matches(in: str, options: [], range: NSRange(location: 0, length: str.utf16.count))

    //Retrieve 1/4 elements of the string
    let randomElementsToReplace = matches.shuffled().dropLast(matches.count * 1/4)

    matches.forEach({ (aMatch) in
        if randomElementsToReplace.first(where: { $0.range == aMatch.range } ) != nil {
            str.replaceSubrange(Range(aMatch.range, in: str)!, with: "_")
        } else {
            //Do nothing because that's the one we are keeping as such
        }
    })
    print("After: \(str)")
} catch {
    print("Error while creating regex: \(error)")
}
Run Code Online (Sandbox Code Playgroud)

它背后的想法:使用与您使用的相同的正则表达式模式.
拾取其中的n个元素(在您的情况下为1/4)
替换不在该短列表中的每个字符.

既然你已经有了这个想法,那么用for循环替换for循环就更快了

for aMatch in randomElementsToReplace {
    str.replaceSubrange(Range(aMatch.range, in: str)!, with: "_")
}
Run Code Online (Sandbox Code Playgroud)

感谢@Martin R的评论,指出它.

输出(完成10次):

$>Before: Hello playground
$>After: ____o ___y____n_
$>Before: Hello playground
$>After: _el__ _______u__
$>Before: Hello playground
$>After: _e___ ____g___n_
$>Before: Hello playground
$>After: H___o __a_______
$>Before: Hello playground
$>After: H___o _______u__
$>Before: Hello playground
$>After: __l__ _____ro___
$>Before: Hello playground
$>After: H____ p________d
$>Before: Hello playground
$>After: H_l__ _l________
$>Before: Hello playground
$>After: _____ p____r__n_
$>Before: Hello playground
$>After: H___o _____r____
$>Before: Hello playground
$>After: __l__ ___y____n_
Run Code Online (Sandbox Code Playgroud)

你会发现你的预期结果有一点不同,这是因为matches.count== 15,所以1/4应该是什么?您可以根据自己的需要(圆形?等)进行正确的计算,因为您没有指定它.

请注意,如果你不想向上舍入,你也可以反过来,使用randomed进行不替换,然后圆形可能对你有利.