Если вы не хотите использовать какие-либо модули из 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);
Основная часть этого RegEx - "(([^\\"]|\\.)*)"
. Подробное описание в виде расширенного регулярного выражения:
/
["'] # 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. Вы можете запретить захват альтернатив $ 2 с помощью скобок в скобках (?:pattern)
. Тогда вы получите этот окончательный результат:
m/["'][uU][tT][tT][eE][rR][aA][nN][cC][eE]["']\s*:\s*["']((?:[^\\"']|\\.)*)["']/gos
Да, иногда Perl выглядит как большой взрыв на фабрике скобок; -)