【问题标题】:Tcl regular expressionsTcl 正则表达式
【发布时间】:2014-06-20 11:01:46
【问题描述】:
set d(aa1) 1 
set d(aa2) 1                                                                                                                   
set d(aa3) 1
set d(aa4) 1
set d(aa5) 1
set d(aa6) 1
set d(aa7) 1
set d(aa8) 1
set d(aa9) 1
set d(aa10) 1
set d(aa11) 1
set regexp "a*\[1-9\]"
set res [array names d -glob $regexp]
puts "res = $res"

在这种情况下,结果是:

res = aa11 aa6 aa2 aa7 aa3 aa8 aa4 aa9 aa5 aa1

但是当我将正则表达式从a*\[1-9\] 更改为a*\[1-10\] 时,结果变为:

res = aa11 aa10 aa1

【问题讨论】:

标签: regex tcl


【解决方案1】:

你的角色类有错误。

  • [1-10] 不是从 1 到 10 的数字
  • 表示1-1,它是一个从11 的字符(即简单的1)或0。这解释了您的输出。
  • 要表示从 1 到 10 的数字,请使用:(?:10?|[2-9])(作为几种方法之一。
  • 因此您的正则表达式变为a*(?:10?|[2-9])
  • 注意,如果你的引擎不允许非捕获组,你需要删除?:,为:a*(?:10?|[2-9])

【讨论】:

  • 很高兴它有帮助。谢谢! :)
【解决方案2】:

您需要确定要匹配的内容,因为glob 样式匹配和regexp 样式匹配在很多方面都不同。

来自the docs,glob 有以下内容:

  • * 匹配字符串中的任何字符序列,包括空字符串。
  • ? 匹配字符串中的任何单个字符。
  • [chars] 匹配由 chars 给出的集合中的任何字符。如果 x-y 形式的序列出现在 chars 中,则 x 和 y 之间的任何字符(包括端点)都将匹配。当与-nocase 一起使用时,范围的端点首先转换为小写。而{[A-z]} 在区分大小写匹配时匹配_(因为_ 介于Za 之间),而-nocase 这被认为类似于{[A-Za-z]}(可能是第一个的意思地点)。
  • \x 匹配单个字符 x。这提供了一种避免模式中字符*?[]\ 的特殊解释的方法。

由于您使用的是 glob 样式匹配,因此您当前的表达式 (a*\[1-9\]) 匹配 a,后跟 any 字符和 1 到 9 中的任何一个(意味着它也将匹配某些内容比如abcjdne1)。

如果您想匹配至少一个 a 后跟从 1 到 10 的数字,您将需要这样的东西,使用 -regexp 模式:

set regexp {a+(?:[1-9]|10)}
set res [array names d -regexp $regexp]

现在,我相信这个正则表达式对于初学者来说更自然((?:[1-9]|10) 表示 1 到 9 或 10,但您可以使用 zx81 建议的形式,(?:10?|[2-9]) 表示 1,可选的 0 10 或 2 到 9)。

+ 表示a 必须至少出现一次才能匹配数组名称。

如果您现在需要匹配全名,则需要使用锚点:

^a+(?:[1-9]|10)$

注意:如果要匹配至少一个 a 后跟数字、交替(使用的管道 |)和量词(?+*),则不能使用全局匹配glob 匹配不支持它们在正则表达式中的行为方式。

最后一件事,使用大括号来避免转义您的模式(除非您有一个变量或在您的模式中运行一个函数并且不能这样做)。

【讨论】:

  • 您可能需要锚定这些 RE;默认情况下,Tcl 不会锚定它们……
猜你喜欢
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多