如果您不想使用 CPAN 中的任何模块并尝试使用正则表达式,您可以尝试多种变体:
# JSON is on a single line:
$json = '{"other":"stuff","hypo":[{"utterance":"hi, this is \"bob\"","moo":0}]}';
# RegEx with negative look behind:
# Match everything up to a double quote without a Backslash in front of it
print "$1\n" if ($json =~ m/"utterance":"(.*?)(?<!\\)"/)
如果只有一个话语,则此正则表达式有效。它周围的字符串中还有什么并不重要,因为它只搜索话语键后面的双引号字符串。
对于更强大的版本,您可以在必要/可能的地方添加空格,并使 RegEx 中的 . 匹配换行符:m/"utterance"\s*:\s*"(.*?)(?<!\\)"/s
如果您有多个话语置信度哈希/对象条目、JSON 字符串的大小写变化和奇怪的格式,请尝试以下操作:
# weird JSON:
$json = <<'EOJSON';
{
"status":0,
"id":"an ID",
"hypotheses":[
{
"UtTeraNcE":"hello my name is \"Bob\".",
"confidence":0.0
},
{
'utterance' : 'how are you?',
"confidence":0.1
},
{
"utterance"
: "
thought
so!
",
"confidence" : 0.9
}
]
}
EOJSON
# RegEx with alternatives:
print "$1\n" while ( $json =~ m/["']utterance["']\s*:\s*["'](([^\\"']|\\.)*)["']/gis);
这个正则表达式的主要部分是"(([^\\"]|\\.)*)"。详细描述为扩展正则表达式:
/
["'] # opening quotes
( # start capturing parentheses for $1
( # start of grouping alternatives
[^\\"'] # anything that's not a backslash or a quote
| # or
\\. # a backslash followed by anything
) # end of grouping
* # in any quantity
) # end capturing parentheses
["'] # closing quotes
/xgs
如果您有许多数据集并且速度是一个问题,您可以将 o 修饰符添加到正则表达式并使用字符类而不是 i 修饰符。您可以使用聚类括号 (?:pattern) 禁止捕获 $2 的替代项。然后你得到这个最终结果:
m/["'][uU][tT][tT][eE][rR][aA][nN][cC][eE]["']\s*:\s*["']((?:[^\\"']|\\.)*)["']/gos
是的,有时 perl 看起来像是支架工厂的一次大爆炸;-)