"whole" 在此 TCL foreach 循环(正则表达式)中的含义
Meaning of "whole" in this TCL foreach loop (regex)
我想了解“whole”关键字在下面的 foreach 循环中的作用。我写了一个正则表达式来查找 | 之间的数字和)在文本中。当我 运行 以下脚本时,请参阅下面的输出。
#!/usr/bin/expect
set text "A(1|1) B(1|3) C(1|6)"
#regex to find numbers between | and )
set pattern {\|([0-9]+)\)}
set matches [regexp -all -inline $pattern $text]
foreach {whole num} $matches {
puts $num
}
puts "---"
foreach num $matches {
puts $num
}
输出:
1
3
6
---
|1)
1
|3)
3
|6)
6
第一个循环输出是想要的,但是为什么当我删除“whole”关键字时第二个循环显示|1),|3)?
您的正则表达式有一个子组 ([0-9]+)
。
因此,在应用 -inline
时,它将 return 包含整个匹配项和第一个子组的列表。
结果不仅限于第一个子组。它基于您提供给表达式的子组数量。例如
% regexp -inline {\d[a-z][A-Z]} "0bX"; # No subgroups
0bX
% regexp -inline {\d[a-z]([A-Z])} "0bX"; # subgroup only for upper-case letters
0bX X
% regexp -inline {\d([a-z])[A-Z]} "0bX"; # subgroup only for lower-case letters
0bX b
% regexp -inline {(\d)[a-z][A-Z]} "0bX"; # subgroup only for digits
0bX 0
% regexp -inline {(\d[a-z])[A-Z]} "0bX"; # subgroup only for digit-lower-case combination
0bX 0b
% regexp -inline {(\d[a-z])([A-Z])} "0bX"; # 1st subgroup is for digit-lower-case and 2nd subgroup is for upper-case letter
0bX 0b X
% regexp -inline {(\d)([a-z])([A-Z])} "0bX"# 1st subgroup is for digit and 2nd subgroup is for lower-case letter and 3rd subgroup is for upper-case letter
0bX 0 b X
%
请注意,在所有这些结果中,始终首先提供整个匹配(即完整匹配),然后提供后续 n
个子组匹配。
这也适用于 -all
标志。因此,对所有匹配重复该过程。
现在,如果我们将此逻辑应用于您的代码,我们将得到以下结果
# 1st whole match, 1st whole match's 1st subgroup, 2nd whole match, 2nd match's 1st subgroup and so on
% set matches [regexp -all -inline $pattern $text];
|1) 1 |3) 3 |6) 6
%
如您所知,regexp -all -inline
生成它匹配的事物的列表,其中该列表每个匹配有多个条目(第一个是完整匹配,后续条目是每个捕获子表达式);它的实际结果是 |1) 1 |3) 3 |6) 6
。 foreach
和 whole
是怎么回事?
嗯,whole
这个词一点也不特别。它只是一个变量名。那种foreach
的一般形式是:
foreach listOfVariableNames listToIterateOver body
{whole num}
是一个包含两个变量名称的列表,因此通过 $matches
的每次迭代我们都会提取列表的两个元素并将它们分配给每个变量。如果尸体是:
puts "whole = '$whole' num = '$num'"
输出应该是:
whole = '|1)' num = '1'
whole = '|3)' num = '3'
whole = '|6)' num = '6'
因为您实际上并没有使用 whole
,所以效果是忽略整体匹配,只使用子表达式匹配。这是一个相当常见的模式。
我想了解“whole”关键字在下面的 foreach 循环中的作用。我写了一个正则表达式来查找 | 之间的数字和)在文本中。当我 运行 以下脚本时,请参阅下面的输出。
#!/usr/bin/expect
set text "A(1|1) B(1|3) C(1|6)"
#regex to find numbers between | and )
set pattern {\|([0-9]+)\)}
set matches [regexp -all -inline $pattern $text]
foreach {whole num} $matches {
puts $num
}
puts "---"
foreach num $matches {
puts $num
}
输出:
1
3
6
---
|1)
1
|3)
3
|6)
6
第一个循环输出是想要的,但是为什么当我删除“whole”关键字时第二个循环显示|1),|3)?
您的正则表达式有一个子组 ([0-9]+)
。
因此,在应用 -inline
时,它将 return 包含整个匹配项和第一个子组的列表。
结果不仅限于第一个子组。它基于您提供给表达式的子组数量。例如
% regexp -inline {\d[a-z][A-Z]} "0bX"; # No subgroups
0bX
% regexp -inline {\d[a-z]([A-Z])} "0bX"; # subgroup only for upper-case letters
0bX X
% regexp -inline {\d([a-z])[A-Z]} "0bX"; # subgroup only for lower-case letters
0bX b
% regexp -inline {(\d)[a-z][A-Z]} "0bX"; # subgroup only for digits
0bX 0
% regexp -inline {(\d[a-z])[A-Z]} "0bX"; # subgroup only for digit-lower-case combination
0bX 0b
% regexp -inline {(\d[a-z])([A-Z])} "0bX"; # 1st subgroup is for digit-lower-case and 2nd subgroup is for upper-case letter
0bX 0b X
% regexp -inline {(\d)([a-z])([A-Z])} "0bX"# 1st subgroup is for digit and 2nd subgroup is for lower-case letter and 3rd subgroup is for upper-case letter
0bX 0 b X
%
请注意,在所有这些结果中,始终首先提供整个匹配(即完整匹配),然后提供后续 n
个子组匹配。
这也适用于 -all
标志。因此,对所有匹配重复该过程。
现在,如果我们将此逻辑应用于您的代码,我们将得到以下结果
# 1st whole match, 1st whole match's 1st subgroup, 2nd whole match, 2nd match's 1st subgroup and so on
% set matches [regexp -all -inline $pattern $text];
|1) 1 |3) 3 |6) 6
%
如您所知,regexp -all -inline
生成它匹配的事物的列表,其中该列表每个匹配有多个条目(第一个是完整匹配,后续条目是每个捕获子表达式);它的实际结果是 |1) 1 |3) 3 |6) 6
。 foreach
和 whole
是怎么回事?
嗯,whole
这个词一点也不特别。它只是一个变量名。那种foreach
的一般形式是:
foreach listOfVariableNames listToIterateOver body
{whole num}
是一个包含两个变量名称的列表,因此通过 $matches
的每次迭代我们都会提取列表的两个元素并将它们分配给每个变量。如果尸体是:
puts "whole = '$whole' num = '$num'"
输出应该是:
whole = '|1)' num = '1'
whole = '|3)' num = '3'
whole = '|6)' num = '6'
因为您实际上并没有使用 whole
,所以效果是忽略整体匹配,只使用子表达式匹配。这是一个相当常见的模式。