正则表达式可选非捕获组

Tra*_*eel 10 javascript regex

我是一个完整的正则表形Noob,花了好几个小时试图解决这个难题.我想我必须使用某种可选的非捕获组或交替.

我想匹配以下字符串:

  1. 诺伊尔电影是冯1000

  2. Neuer Film a von 1000 mit b

  3. Neuer Film a von 1000 mit b und c

  4. Neuer Film a von 1000 mit b und c und d

  5. Neuer Film a mit b

  6. Neuer Film a mit b und c

  7. Neuer Film a mit b und c und d

我的正则表达式如下:

var regex = /(?:[nN]euer [Ff]ilm\s?)(.*)(?:[vV]on).(\d{4}).(?:[Mm]it)(.*)(?:[uU]nd)(.*)/g;
Run Code Online (Sandbox Code Playgroud)

问题是它只匹配字符串3和4.它与最后两个"und"不匹配,但是将它打包在组No.3中而不是组No.4中.

有人可以帮助我的正则表达式(这对用户不是很友好;)

Wik*_*żew 9

你真的需要使用非捕获可选组(比如(?:...)?),但此外,你还需要锚点(^匹配字符串的开头并$匹配字符串结束)和懒惰点匹配模式(.*?以匹配任何字符作为可能).

你可以用

/^[nN]euer [Ff]ilm\s*(.*?)(?:\s*[vV]on\s+(\d{4}))?(?:\s+[Mm]it\s*(.*?)(?:\s*[uU]nd\s*(.*))?)?$/
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示.在演示中,/gm修饰符是必需的,因为输入是多行字符串.

图案细节:

  • ^ - 开始一个字符串锚
  • [nN]euer [Ff]ilm- Neuer film/ Neuer Film/neuer Film
  • \s* - 零个或多个空格
  • (.*?)- 第1组:除了换行符之外的任何0+字符,尽可能少(即,直到后续子模式的最左侧出现)
  • (?:\s*[vV]on\s+(\d{4}))? - 1次或0次出现:
    • \s* - 0+空格
    • [vV]on- vonVon
    • \s+ - 1+个空格
    • (\d{4}) - 第2组:4位数
  • (?:\s+[Mm]it\s*(.*?)(?:\s*[uU]nd\s*(.*))?)? - 可选的非捕获组,匹配1或0次出现:
    • \s+ - 1+个空格
    • [Mm]it - Mitmit
    • \s* - 0+空格
    • (.*?) - 第3组匹配除了换行符之外的任何0+字符,尽可能少
    • (?:\s*[uU]nd\s*(.*))? - 可选的非捕获组匹配
      • \s*[uU]nd\s*- undUnd用0+空格括起来
      • (.*) - 第4组尽可能多地匹配除换行符之外的任何0+字符
  • $ - 字符串结尾.

var strs = ['Neuer Film a von 1000','Neuer Film a von 1000 mit b','Neuer Film a von 1000 mit b und c','Neuer Film a von 1000 mit b und c und d','Neuer Film a mit b','Neuer Film a mit b und c','Neuer Film a mit b und c und d'];
var rx = /^[nN]euer [Ff]ilm\s*(.*?)(?:\s*[vV]on\s+(\d{4}))?(?:\s+[Mm]it\s*(.*?)(?:\s*[uU]nd\s*(.*))?)?$/;
for (var s of strs) {
   var m = rx.exec(s);
   if (m) {
     console.log('-- ' + s + ' ---');
     console.log('Group 1: ' + m[1]);
     if (m[2]) console.log('Group 2: ' + m[2]);
     if (m[3]) console.log('Group 3: ' + m[3]);
     if (m[4]) console.log('Group 4: ' + m[4]);
   }
   
}
Run Code Online (Sandbox Code Playgroud)

  • `.*?` 匹配尽可能少的字符,因此,正则表达式到达 `und` 的*最左侧出现位置*(与 `\s*[uU]nd\s*` 匹配,未捕获)。请注意,惰性模式不匹配 2 个字符串之间的*最短*子字符串(如某些 SO 答案中所述),它们只是匹配后续子模式的最左边出现的位置。 (2认同)