-line 标志在 tcl 正则表达式中有什么作用?

What does -line flag do in tcl regular expression?

下面复制了我写的代码。不知道line flag是干什么的

set value "hi this is venkat345
hi this is venkat435
hi this is venkat567"

regexp -all -line -- {(venkat.+)$} $value a b  
puts "Full Match: $a"
puts "Sub Match1: $b"

以上代码输出如下

Full Match: venkat567
Sub Match1: venkat567

任何人都可以解释一下我应该何时何地选择 tcl 正则表达式中的 -line 标志

-line 只需确保您的 . 永远不会匹配换行符。

根据 Tcl regexp documentation:

-line

Enables newline-sensitive matching. By default, newline is a completely ordinary character with no special meaning. With this flag, ‘[^’ bracket expressions and ‘.’ never match newline, ‘^’ matches an empty string after any newline in addition to its normal function, and ‘$’ matches an empty string before any newline in addition to its normal function. This flag is equivalent to specifying both -linestop and -lineanchor, or the (?n) embedded option (see METASYNTAX, below).

这是没有 -line 选项的输出:

Full Match: venkat345                                                                                                                                                                                                                                  
hi this is venkat435                                                                                                                                                                                                                                   
hi this is venkat567                                                                                                                                                                                                                                   
Sub Match1: venkat345                                                                                                                                                                                                                                  
hi this is venkat435                                                                                                                                                                                                                                   
hi this is venkat567

.+ 只匹配到 value 字符串结尾的所有行。

man page 已经很好地定义了我相信:

-line

Enables newline-sensitive matching. By default, newline is a completely ordinary character with no special meaning. With this flag, [^ bracket expressions and . never match newline, ^ matches an empty string after any newline in addition to its normal function, and $ matches an empty string before any newline in addition to its normal function. This flag is equivalent to specifying both -linestop and -lineanchor, or the (?n) embedded option (see the re_syntax manual page).

如果换个方式理解,.[^ ... ]通常匹配换行符,例如:

regexp -- {^....$} "ab\nc"

returns 1(表示正则表达式匹配字符串,将 \n 计为 1 个字符)但使用 -line 开关将阻止 .匹配 \n.

相似:

regexp -- {^[^abc]+$} "de\nf"

也将 return 1 因为取反的 class [^abc] 能够匹配非 abc 的字符,其中包括 \n.

-line 开关的第二个函数使 ^ 在每个行的开头匹配,而不是仅在整个字符串的开头匹配,并使 $ 在每个行匹配行尾而不是仅在整个字符串的末尾匹配。

% set text {abc
abc}
abc
abc
% regexp -- {^abc$} $text
0
% regexp -line -- {^abc$} $text
1

至于何时何地,这取决于你想做什么。根据您的示例代码,在我看来,您需要获取所有以 venkat 开头的用户名,这些用户名可以出现在任何行的末尾。由于你想匹配很多,你需要使用 -all-inline 开关来获取匹配的字符串,我建议稍微更改正则表达式:

set value "hi this is venkat345
hi this is venkat435
hi this is venkat567"

# I removed the capture group and changed . to \S to match non-space characters
set results [regexp -all -inline -line -- {venkat\S+$} $value]
puts $results
# venkat345 venkat435 venkat567