Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Regexp重复行匹配无法正常工作_Javascript_Regex_Duplicate Removal - Fatal编程技术网

Javascript Regexp重复行匹配无法正常工作

Javascript Regexp重复行匹配无法正常工作,javascript,regex,duplicate-removal,Javascript,Regex,Duplicate Removal,我正在编写一个Javascript代码来解析一些语法文件,这是相当多的代码,但我将在这里发布相关信息。我使用Javascript Regexp来匹配字符串中的重复行。该字符串包含,例如(假定字符串名称为lines): 它永远不会进入if(m)语句。因此没有找到匹配项。我在这里测试了正则表达式:在代码中使用正则表达式以及提供的示例文本。比赛很好,所以我有点不知所措。如果有人能帮忙,那就太好了 多谢各位 编辑: 忘了添加,我正在firefox中测试,它只需要在firefox中工作。不知道这是否重要

我正在编写一个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");