当行包含不平衡的大括号时,我在此正则表达式中收到错误消息。
set line "a b { c{}"
set lst [regexp -all -inline {^(\s*(\S*)\s*)*(\{(.*)\})?(\s*(\S*)\s*)*$} $line]
set lst [lindex $lst 0]
set firstelement [lindex $lst 0]
如何避免此类案件并将不平衡的大括号视为一个词?
答案 0 :(得分:1)
regexp命令返回一个列表。然后,您将获取列表的第一个元素。但是在最后一行中,您将该元素视为一个列表 - 但不能保证这样 - 因此实际的字符串内容很重要。相反,如果您要将此项目作为列表处理,则需要使用split
并将其转换为单词:
% split "a b {" " "
a b \{
在你的情况下:
set lst [lindex $lst 0]
set firstelement [lindex [split $lst " "] 0]
您可能还想查看subst
。看起来您正在尝试将指定不佳的tcl列表作为输入读取并进行一些解析以将它们作为正确的tcl列表。在这种情况下,subst -nocommands [lindex $lst 0]
可能对您更有帮助。例如:
% lindex [subst -nocommands [lindex $lst 0]] 2
c{}
请注意,这是$ line的支撑部分的内容。
答案 1 :(得分:1)
当你有来自任意来源(如用户)的字符串时,根本不能保证它是一个结构良好的列表。现在regexp -inline
返回匹配的列表,但该列表的元素是字符串(当然,除非你使用-indices
选项),这意味着你不能安全地使用{{1在他们身上挑出碎片。
获取第一个“单词”的安全方法,假设您将“单词”定义为“非空白字符序列”(通常的用户定义),就是这样做:
lindex
这有点难看,但它完全安全。 (事实上,对于第一个单词,请单独使用set firstWord [lindex [regexp -all -inline {\S+} $item] 0]
,但这不会让您获得以后的单词。)
使用regexp -inline {\S+} $item
将字符串分解为单词也是可能的,但是强烈假设单词分隔符是单个(默认为空格)字符,并且如果您有多个字符,则执行您可能不期望的操作-whitespace分隔符,或前导和尾随空格。坦率地说,将非空格分隔的字符串(例如,文件分为行,split
记录到字段中)或将字符串转换为字符列表(使用空的第二个参数)更有用。