正则表达式 - SubExpressions - IMDB

时间:2013-09-08 06:33:56

标签: javascript regex

我正在尝试使用正则表达式来标记我从IMDB的文本界面下载的电影标题。

RE的简化版本将证明我遇到的问题。这是一个标题示例:

"'Allo 'Allo!" (1982)
"A film in production" (????)

我可以这样匹配:

re=/(\".*\")\s(\(.{4}\));

然后我可以使用子表达式在javascript中对电影进行标记,就像这样:

titleParts = rawTitle.match(re);
console.log('title %s', titleParts[0]);

但后来我发现了这样的电影片名:

Unquoted film title  (2012)

因为标题周围没有引号,我无法再将这些元素匹配到子表达式中:

re=/((\"){0,1}.*(\"){0,1})\s(\(.{4}\));

请注意,我已通过指定引号是可选的来更改原始RE。但现在发生的是整个字符串匹配第一个subExpression。

如何解决这个问题?

4 个答案:

答案 0 :(得分:3)

您的标题实际上位于索引1而不是0

console.log('title %s', titleParts[1]); // "title Unquoted film title "

你不应该在标题周围捕捉引号和空格。这会导致标题显示不一致:有时引用,有时不引用;或者,需要字符串操作,这是不必要的,应该避免。

如果您的标题字符串始终具有(year)部分,并假设IMDB将在电影标题中使用单引号(例如您的示例中),那么您的正则表达式可以简化为

"?(.*?)"?\s+\((.{4})\)

这里有一些JavaScript可以一致地打印带引号的标题:

var titles = [
    "\"'Allo 'Allo!\" (1982)",
    "\"A film in production\" (????)",
    "Hachi: A Dog's Tale (2009)"
];

var re = /"?(.*?)"?\s+\((.{4})\)/;

for each ( var t in titles ) {
    var titleParts = t.match(re);
    console.log('Title: "%s" ; Year: %s', titleParts[1], titleParts[2]);
}

输出:

Title: "'Allo 'Allo!" ; Year: 1982
Title: "A film in production" ; Year: ????
Title: "Hachi: A Dog's Tale" ; Year: 2009

答案 1 :(得分:0)

我在regexpal中尝试了这个表达式^("?[\w\s!']+"?)\s\((.{4})\)$,它适用于所有情况。

答案 2 :(得分:0)

永远不要使用正则表达式来实现强大的标记化解决方案。标记很难,我保证你会遇到更多你尚未遇到的边缘情况。

请改用:

https://npmjs.org/package/tokenizer

答案 3 :(得分:0)

你的问题是贪婪的量词.*,它总是匹配(空字符串也是如此)。您可以使用更具体的内容来捕获标题,例如prasanth的建议[\w\s!']+但是您可能需要更多标点字符,或者您使用占有量词.+?(我更喜欢+而不是{{1}在这里,因为你想要抓住东西)。所以你的正则表达式将是:

*