Javascript Regexp重复行匹配无法正常工作
我正在编写一个Javascript代码来解析一些语法文件,这是相当多的代码,但我将在这里发布相关信息。我使用Javascript Regexp来匹配字符串中的重复行。该字符串包含,例如(假定字符串名称为lines): 它永远不会进入if(m)语句。因此没有找到匹配项。我在这里测试了正则表达式:在代码中使用正则表达式以及提供的示例文本。比赛很好,所以我有点不知所措。如果有人能帮忙,那就太好了 多谢各位 编辑: 忘了添加,我正在firefox中测试,它只需要在firefox中工作。不知道这是否重要Javascript Regexp重复行匹配无法正常工作,javascript,regex,duplicate-removal,Javascript,Regex,Duplicate Removal,我正在编写一个Javascript代码来解析一些语法文件,这是相当多的代码,但我将在这里发布相关信息。我使用Javascript Regexp来匹配字符串中的重复行。该字符串包含,例如(假定字符串名称为lines): 它永远不会进入if(m)语句。因此没有找到匹配项。我在这里测试了正则表达式:在代码中使用正则表达式以及提供的示例文本。比赛很好,所以我有点不知所措。如果有人能帮忙,那就太好了 多谢各位 编辑: 忘了添加,我正在firefox中测试,它只需要在firefox中工作。不知道这是否重要
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
表示每个参数
对象,因此m0
是整个匹配,m1
是第一个子组((^\n)
),m2
是第二个子组(([^\n]*)
),而m3
是最后一个子组(((\n\2)
)。我本可以使用参数[n]
来代替,但这些参数较短
与返回值一样,由于Javascript使用的regex风格中缺少lookback,此模式正在捕获可能的前一个换行符(除非它是第一行),因此需要返回匹配项和前一个换行符(如果有)。这就是为什么它不应该只返回m2
。第一个错误:\
在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
构造函数,将模式作为字符串传递给构造函数。这意味着您需要转义模式中出现的每个\
反斜杠。如果使用regexp文本,则不需要转义它们,因为它们不在字符串中,而是在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");
最后,该方法只检测两条连续的相同直线。这就是您想要的,还是您需要检测任何重复项,无论它们可能在哪里?是的,它只需要检测连续的相同行。我记得将var re=//g更改为var re='//g',但我不知道为什么,这是一个错误。对于转义字符,我甚至没有想到它是一个字符串,我必须转义它们。谢谢你的回复,如果我让它工作,我会更新。m0,m1,m3的功能是什么?该函数返回m1+m2,但它将保持什么值?我没有看到m1在任何地方被使用。@Dohrann我在我的回答中添加了这个解释,让大家看看这些参数发生了什么。我现在明白了,谢谢,尽管这与第18行和第20行匹配。因此它匹配第一个“test2”和之后的“空”空格。这我不明白。此外,replace没有正确替换,字符串仍然返回它之前的内容。@Dohrann我提供的代码会查找连续的相同行,并删除最后一行之后的所有行,它是根据您在上一个答案中发布的问题和注释编写的。如果这不是你问的问题,你需要编辑你的问题。@Dohrann我忘记了str=
之前的str.replace(…)
部分。很抱歉。顺便说一句,它适用于我尝试的所有浏览器。
lines = lines.replace(rex,""); //Gets rid of the duplicate
lines = lines.replace(rex, "$1");