我是Java的新手,我在现有代码中找到了一个循环,看起来它应该是一个无限循环(或者具有非常不受欢迎的行为),它实际上有效。
你能解释一下我错过了什么吗?我认为它应该是无限的原因是,根据这里的文档(https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html#replaceAll-java.lang.String-),对replaceAll的调用将重置匹配器(此方法首先重置此匹配器。然后它扫描输入序列...... )。所以我认为下面的代码会替换它,然后再次调用find(),这将从头开始。并且它将继续查找相同的字符串,因为您可以看到字符串刚刚被包裹在标记中。
如果不明显,Pattern和Matcher是java.util.regex中的类。
String aTagName = getSomeTagName()
String text = getSomeText()
Pattern pattern = getSomePattern()
Matcher matches = pattern.matcher(text);
while (matches.find()) {
text = matches.replaceAll(String.format("<%1$s> %2$s </%1$s>", aTagName, matches.group()));
}
为什么不是这样?
答案 0 :(得分:1)
我怀疑此代码很可能是无意的,因为import tensorflow as tf
# Function in python
def dummy(x):
return [x,x]
print(dummy([1.0,2.0]))
tf_fun = tf.py_func(dummy,[[1.0,2.0]],(tf.float32,tf.float32))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(tf_fun))
更改了状态,并且由于它扫描要替换的字符串,结果是仅执行1次搜索并且声明的群组用于替换此群组的所有搜索。
replaceAll
当String text = "abcdEfg";
Pattern pattern = Pattern.compile("[a-z]");
Matcher matches = pattern.matcher(text);
while (matches.find()) {
System.out.println(text); // abcdEfg
text = matches.replaceAll(matches.group());
System.out.println(text); // aaaaEaa
}
告诉匹配器扫描字符串时,它最终将指针移动到末尾以耗尽整个字符串的状态。然后replaceAll
恢复搜索(从当前状态 - 这是结束,而不是开始),但搜索已经用尽。
适当地迭代和替换每个组的正确方法之一可能是使用find
:
appendReplacement
答案 1 :(得分:1)
以下示例显示如果您使用全部替换,则没有理由调用while循环。在这两种情况下,答案都是
夏天? 是 炎热的夏天。 是不是吗?
function New-SWRandomPassword {
[CmdletBinding(DefaultParameterSetName='FixedLength',ConfirmImpact='None')]
[OutputType([String])]
Param
(
# Specifies minimum password length
[Parameter(Mandatory=$false,
ParameterSetName='RandomLength')]
[ValidateScript({$_ -gt 0})]
[Alias('Min')]
[int]$MinPasswordLength = 8,
# Specifies maximum password length
[Parameter(Mandatory=$false,
ParameterSetName='RandomLength')]
[ValidateScript({
if($_ -ge $MinPasswordLength){$true}
else{Throw 'Max value cannot be lesser than min value.'}})]
[Alias('Max')]
[int]$MaxPasswordLength = 11,
# Specifies a fixed password length
[Parameter(Mandatory=$false,
ParameterSetName='FixedLength')]
[ValidateRange(1,2147483647)]
[int]$PasswordLength = 10,
# Specifies an array of strings containing charactergroups from which the password will be generated.
# At least one char from each group (string) will be used.
[String[]]$InputStrings = @('abcdefghijkmnpqrstuvwxyz', 'ABCEFGHJKLMNPQRSTUVWXYZ', '23456789', '!"#%&'),
# Specifies a string containing a character group from which the first character in the password will be generated.
# Useful for systems which requires first char in password to be alphabetic.
[String] $FirstChar,
# Specifies number of passwords to generate.
[ValidateRange(1,2147483647)]
[int]$Count = 1
)
Begin {
Function Get-Seed{
# Generate a seed for randomization
$RandomBytes = New-Object -TypeName 'System.Byte[]' 4
$Random = New-Object -TypeName 'System.Security.Cryptography.RNGCryptoServiceProvider'
$Random.GetBytes($RandomBytes)
[BitConverter]::ToUInt32($RandomBytes, 0)
}
}
Process {
For($iteration = 1;$iteration -le $Count; $iteration++){
$Password = @{}
# Create char arrays containing groups of possible chars
[char[][]]$CharGroups = $InputStrings
# Create char array containing all chars
$AllChars = $CharGroups | ForEach-Object {[Char[]]$_}
# Set password length
if($PSCmdlet.ParameterSetName -eq 'RandomLength')
{
if($MinPasswordLength -eq $MaxPasswordLength) {
# If password length is set, use set length
$PasswordLength = $MinPasswordLength
}
else {
# Otherwise randomize password length
$PasswordLength = ((Get-Seed) % ($MaxPasswordLength + 1 - $MinPasswordLength)) + $MinPasswordLength
}
}
# If FirstChar is defined, randomize first char in password from that string.
if($PSBoundParameters.ContainsKey('FirstChar')){
$Password.Add(0,$FirstChar[((Get-Seed) % $FirstChar.Length)])
}
# Randomize one char from each group
Foreach($Group in $CharGroups) {
if($Password.Count -lt $PasswordLength) {
$Index = Get-Seed
While ($Password.ContainsKey($Index)){
$Index = Get-Seed
}
$Password.Add($Index,$Group[((Get-Seed) % $Group.Count)])
}
}
# Fill out with chars from $AllChars
for($i=$Password.Count;$i -lt $PasswordLength;$i++) {
$Index = Get-Seed
While ($Password.ContainsKey($Index)){
$Index = Get-Seed
}
$Password.Add($Index,$AllChars[((Get-Seed) % $AllChars.Count)])
}
Return $(-join ($Password.GetEnumerator() | Sort-Object -Property Name | Select-Object -ExpandProperty Value))
}
}
}
New-SWRandomPassword