这个问题是关于理解 Vivado中内置的TCL 8.5中特定正则表达式的行为,特别是在or
两个正则表达式部分中我得到了意想不到的结果:
我致力于使用正则表达式缩进命令行的文本块.我的第一个想法是用缩进来替换每个newline
用一个newline
和一些spaces
(X
在这里为了清楚起见),所以:
puts [regsub -all "\n" "foo\nBar\nBaz" "\nXX"]
foo
XXBar
XXBaz
Run Code Online (Sandbox Code Playgroud)
这不会缩进第一行,以匹配我使用的第一行^
:
puts [regsub -all "^" "foo\nBar\nBaz" "\nXX"]
XXfoo
Bar
Baz
Run Code Online (Sandbox Code Playgroud)
现在应该只是将两个正则表达式部分组合在一起|
,但是我得到输出我无法解释:
puts [regsub -all "^|\n" "foo\nBar\nBaz" "\nXX"]
XXfoo
XX
XXBar
XX
XXBaz
Run Code Online (Sandbox Code Playgroud)
附加新行和标识符(X
)来自哪里?为什么看起来我有两次换人?这是一个错误,还是我对正则表达式语法有点不了解?
对于completnes来说,这是我现在使用的正则表达式 puts [regsub -all -line "^" "foo\nBar\nBaz" "XX"]
我认为解释取决于这样一个事实:表达式^
被视为基本正则表达式 (BRE),但是当您添加它时|
,它会被视为高级正则表达式 (ARE),高级正则表达式 (ARE) 是扩展正则表达式 (ERE) 的超集。这是基于re_syntax 手册页中的以下内容:
\n\n\nARE 是一个或多个分支,由 \xe2\x80\x9c|\xe2\x80\x9d 分隔,匹配与任何分支匹配的任何内容。
\n
难题的第二部分是^
在基本正则表达式和扩展/高级正则表达式中的处理方式不同。在基本正则表达式中,^
仅当它是表达式的第一个字符时才具有特殊含义。再次,来自re_syntax 手册页:
\n\n\nBRE 在几个方面与 ERE 不同... ^ 是一个普通字符,除了在 RE 开头或带括号的子表达式的开头之外,...
\n
换句话说,对于 BRE,^
将仅匹配字符串的开头,但在 ARE 中,它将匹配行的开头。
那么,究竟发生了什么?
\n\n首先,^
匹配字符串的开头,因此它用 replacement 替换它\\nXX
。接下来,它会看到f
、then o
、then o
,没有一个匹配。然后它看到它匹配的 \'\\n`,因此它用替换项替换它。
此时匹配器已经消耗了字符foo\\n
。剩下的就是Bar\\nBaz
。匹配器现在查看该字符串,并且模式^
匹配,因此它再次用替换项替换它。因此,您最终会得到替换字符串的两份副本,一份用于换行符,一份用于保留字符串的开头。
如果您的最终目标是为每一行添加缩进,则可以使用 regsub 进行换行敏感匹配,然后用于^
匹配包括第一行在内的每一行,而不是尝试同时匹配换行符和字符串的开头。--line
您可以通过将选项添加到 来完成此操作regsub
。例如:
regsub -line -all "^" "foo\\nBar\\nBaz" "XX" t; puts $t\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
165 次 |
最近记录: |