我正在编写一个Javascript代码来解析一些语法文件,这是一些代码,但我会在这里发布相关信息。我使用Javascript Regexp来匹配字符串中的重复行。例如,字符串包含(假设字符串名称是行):
if else ; print { } test1 test1 = + - * / ( ) num string comment id test2 test2
应该发生什么,是'test1'和'test2'上的匹配。然后应删除副本,留下1个test1和test2实例。发生的事情根本不配。我对我的正则表达式很有信心,但javascript可能正在做一些我没想到的事情。以下是对上面给出的字符串进行处理的代码:
var rex = new RegExp("(.*)(\r?\n\1)+","g");
var re = '/(.*)(\r?\n\1)+/g';
rex.lastIndex = 0;
var m = rex.exec(lines);
if (m) {
alert("Found Duplicate");
var linenum = lines.search(re); //Get line number of error
alert("Error: Symbol Defined twice\n");
alert("Error occured on line: " + linenum);
lines = lines.replace(rex,""); //Gets rid of the duplicate
}
它永远不会进入if(m)语句。因此找不到匹配项。我在这里测试了正则表达式:http://regexpal.com/使用我的代码中的正则表达式以及提供的示例文本。它匹配得很好,所以我有点失落。如果有人可以提供帮助,那就太好了。
谢谢。
编辑: 忘了添加,我在firefox中测试它,它只需要在firefox中工作。不确定这是否重要。
答案 0 :(得分:0)
var str = 'if\nelse\n;\nprint\n{\n}\ntest1\ntest1\n=\n+\n-\n*\n/\n(\n)\nnum\nstring\ncomment\nid\ntest2\ntest2\ntest2\ntest2\ntest2';
console.log(str);
str = str.replace(/\r\n?/g,'');
// I prefer replacing all the newline characters with \n's here
str = str.replace(/(^|\n)([^\n]*)(\n\2)+/g,function(m0,m1,m2,m3,ind) {
var line = str.substr(0,ind).split(/\n/).length + 1;
var msg = '[Found duplicate]';
msg += '\nFollowing symbol defined more than once';
msg += '\n\tsymbol: ' + m2;
msg += '\n\ton line ' + line;
console.log(msg);
return m1 + m2;
});
console.log(str);
否则,您可以跳过第一行并将模式更改为
/(^|\r\n?|\n)([^\r\n]*)((?:\r\n?|\n)\2)+/g
请注意,[^\n]*
也会捕获多个空行。如果你想确保它匹配(并替换)非空行,那么你可能想要使用[^\n]+
。
<强> [编辑] 强>
对于记录,每个m
代表每个arguments
对象,因此m0
是整个匹配,m1
是第一个子组((^|\n)
), m2
是第二个子组(([^\n]*)
),m3
是最后一个子组((\n\2)
)。我可以使用arguments[n]
代替,但这些更短。
与返回值一样,由于Javascript使用的正则表达式缺乏lookbehind,此模式捕获可能的前一个换行符(除非它是第一行)所以它需要返回匹配和前一个换行符if任何。这就是为什么它不应该只返回m2
。
答案 1 :(得分:0)
第一个错误:JS字符串中的\
也是转义字符。
var rex = new RegExp("(.*)(\r?\n\1)+","g");
应该写
var rex = new RegExp("(.*)(\\r?\\n\\1)+","g");
// or, shorter:
var rex = /(.*)(\r?\n\1)+/g;
如果你想让它发挥作用。在RegExp
构造函数的情况下,您将模式作为字符串传递给构造函数。这意味着您需要转义模式中出现的每个\
反斜杠。如果使用正则表达式文字,则不需要转义它们,因为它们不在字符串中,而是在正则表达式模式中保留它们的“正常”属性。
第二个错误,你的表达
var re = '/(.*)(\r?\n\1)+/g';
错了。你在这里做的是为变量分配字符串文字。我假设您打算分配一个正则表达式文字,应该这样写:
var re = /(.*)(\r?\n\1)+/g;
第三次错误:最后一行
lines = lines.replace(rex,""); //Gets rid of the duplicate
删除所有重复行的两个实例!如果要保留每个副本的第一个实例,则应使用
lines = lines.replace(rex, "$1");
最后,此方法仅检测两个连续相同的行。这是你想要的,还是你需要检测任何重复项,无论它们在哪里?