使用正则表达式在标签之间提取字符串

时间:2016-12-19 21:50:57

标签: regex tcl

我有以下字符串

------------------------------------------------------------------------
r100 | dawson | 2012-10-3 04:21:27 -0600 (Wed, 3 Oct 2012) | 8 lines
Changed paths:
   M /branches/project/foo.cpp
   A /branches/project/foo1.cpp
   D /branches/project/foo2.cpp

:SUMMARY: Add new file
:Module:

------------------------------------------------------------------------

现在我要做的是,列出已为特定提交更改的所有文件。为此,我首先需要在标签和#34;更改路径之间提取信息:"和":摘要:" ,我的正则表达式解决方案不是很整洁。当我这样做时,

set blocks [regexp -nocase -lineanchor -inline -all -- {^\s*?Changed paths\s*?:\s*?.*?:} $summary]

其中$ summary是上面的字符串内容,我的输出是,

{Changed paths:
   M /branches/project/foo.cpp
   A /branches/project/foo1.cpp
   D /branches/project/foo2.cpp

:}

预期产出:

   M /branches/project/foo.cpp
   A /branches/project/foo1.cpp
   D /branches/project/foo2.cpp

我似乎无法摆脱"改变路径:" 。我没有这方面的经验,任何人都可以指出我做错了什么,如果有办法将这些已更改的文件存储在列表中可能会?

2 个答案:

答案 0 :(得分:1)

您需要使用捕获括号来包装正则表达式模式的一部分以获取所需的子字符串,然后指定一个将保存regexp中的值的变量:

Changed paths\s*?:\s*?(.*?):SUMMARY
                      ^^^^^

请参阅下面的演示:

set summary {------------------------------------------------------------------------
r100 | dawson | 2012-10-3 04:21:27 -0600 (Wed, 3 Oct 2012) | 8 lines
Changed paths:
   M /branches/project/foo.cpp
   A /branches/project/foo1.cpp
   D /branches/project/foo2.cpp

:SUMMARY: Add new file
:Module:

------------------------------------------------------------------------}
regexp {\n\s*?Changed paths\s*?:\s*?(.*?):SUMMARY} $summary - blocks
puts $blocks

请参阅Tcl online demo

如果Changed paths出现在字符串的开头,请使用^代替\n

$summary - blocks表示:我们将$summary字符串传递给regexp,并丢弃整个匹配值(-)并将Capture组1内容分配给{ {1}}变量。

答案 1 :(得分:0)

您也可以使用(根据您的示例)

regexp -nocase -line -inline -all {^\s+.*$} $summary

regexp -nocase -line -inline -all {^.*\.cpp$} $summary