我正在尝试从 BASIC 代码中提取 GOTOs/GOSUBs 行号。我打算使用 NodeJS 来管理匹配(所以它是 JS-flavored Regex)。
我正在使用 regex101.com(见这里 https://regex101.com/r/SaZuue/2 )进行测试,我非常接近我想要的:
GOTO ###
提取为 ["GOTO", " ", "###"]
GOSUB ###
提取为 ["GOSUB", " ", "###"]
IF (cond) THEN ###
提取为 ["THEN", " ", "###"]
ON ERR GOTO #, ##, ###
提取为 ["GOTO", " ", "#", ", ", "##", ", ", "###"]
ON ERR GOSUB
GOTO
、 GOSUB
、 THEN
和 ,
之间的空格是可选的,也可以是多个,并且在所有情况下都返回指定的确切空格数。 到目前为止,我已经提出了以下正则表达式:
/(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
除了只返回第一个和最后一个数字(10000 和 800)而不返回其他数字的
ON ERR GOTO
之外,所有匹配的组都可以。我错过了什么?谢谢 :)
最佳答案
使用正则表达式无法获得任意数量的捕获,也无法使用 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)] );
}
关于javascript - 使用正则表达式提取 GOTO/GOSUB 的行号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46151114/