使用Regex提取GOTO / GOSUB的行号

时间:2017-09-11 08:18:36

标签: javascript node.js regex

我试图从BASIC代码中提取GOTO / GOSUB的行号。我打算使用NodeJS来管理匹配(所以它是JS风格的正则表达式)。

我正在使用regex101.com进行测试(请参阅此处https://regex101.com/r/SaZuue/2),而且我非常接近我想要的内容:

  • GOTO ###提取为["GOTO", " ", "###"]
  • GOSUB ###提取为["GOSUB", " ", "###"]
  • IF (cond) THEN ###提取为["THEN", " ", "###"]
  • ON ERR GOTO #, ##, ###提取为["GOTO", " ", "#", ", ", "##", ", ", "###"]
  • 与上述相同,但ON ERR GOSUB
  • 处理GOTOGOSUBTHEN,之间的空格是可选的,或者可以是多个空格,并且在所有情况下都返回指示的确切空格数

到目前为止,我已经提出了以下正则表达式:

/(GOTO|GOSUB|THEN)(\s*)(\d+)(?:(\s*,\s*)(\d+))*/ig

测试:

100 ON ERR GOTO 10000, 30, 200, 10,800: GOSUB 20: IF A THEN 10: GOTO30: GOTO 50

除了ON ERR GOTO之外,所有匹配组都没问题,Allowed memory size of 2097152 bytes exhausted只返回第一个和最后一个数字(10000和800),而不返回其他数字。

我错过了什么?谢谢:))

1 个答案:

答案 0 :(得分:3)

使用正则表达式无法获得任意数量的捕获,并且无法使用JS RegExp访问单个组中的多个捕获,因为它不会为每个组存储捕获值堆栈(后续捕获重写现有的,因此,每组只存储最后一次捕获。)

捕获逗号分隔数字的条纹,然后拆分以分别获取它们。例如。使模式的结尾看起来像((?:\s*,\s*\d+)*)(以匹配0+序列的,,其中包含0+空格,后跟1+位数)然后,在匹配时,用/\s*,\s*/分割并过滤。

参见JS演示:



var rx = /\b(GO(?:TO|SUB)|THEN)(\s*)(\d+)((?:\s*,\s*\d+)*)/gi;
var str = "100 ON ERR GOTO 10000, 30,   200, 10,800: GOSUB 20: IF A THEN 10: GOTO30: GOTO  50";
var m;
while ((m = rx.exec(str)) !== null) {
   console.log( [m[1], m[2], m[3], m[4].split(/\s*,\s*/).filter(Boolean)] );
}