用于解析JSON之类的正则表达式,如文本

问题描述

| 我有形式的正则表达式:
Field1:Value
Field2:Value
Field3:Value

Field1:Value
Field2:Value
Field3:Value

Field1:Value
Field2:Value
Field3:Value

Field1:Value
Field2:Value
Field3:Value
冒号左侧的内容是标准字母字符(
[a-zA-Z]
),第一个字符始终以大写字母开头。它们只能是Field1或Field2或Field3。但是,右边的值可以跨越多行,并且可以包含任何字符:
[a-zA-Z]
,空格,
$
%
^
等。我正在尝试使用一个与{Field1:value} {Field2:value匹配的正则表达式} {Field3:value}分别在TCL中。     

解决方法

通常,我会先将数据解析成几行,然后为每行分配一个解释(例如,起始行或续行),然后将起始行与其后续的续行合并(形成“逻辑”行)。只有这样做之后,我才可以使用RE从值中拆分键。作为格式的建议,如果行以空格开头,请尝试使其连续。这很容易实现,并且在文件中看起来不错。 作为代码:
# Read the data from a file and split into lines
set f [open \"filename\"]
set lines [split [read $f] \"\\n\"]
close $f

# Recombine into logical lines
set logicalLines {}
foreach realline $lines {
    if {[regexp \"^ (.*)\" $realline -> tail]} {
        append current \"\\n$tail\"
    } else {
        if {[info exist current]} {
            lappend logicalLines $current
        }
        set current $realline
    }
}
lappend logicalLines $current         ;# Assume at least one line :-)

# Parse the logical lines
foreach line $logicalLines {
    if {[regexp {^([A-Z]\\w+):(.*)$} $line -> key value]} {
        # OK,got $key mapping to $value
    } else {
        # It\'s a bogus line; waaaah!
    }
}
好的,合并线条可能有不同的规则,但是通过将事情分成两个阶段,可以使您的生活更加轻松。同样,可以对行的有效性使用更严格的测试(例如,将
([A-Z]\\w+)
替换为
(Field[123])
),但我不认为这实际上是明智的。