【问题标题】:Finding the difference between two string in Javascript with regex [closed]使用正则表达式查找 Javascript 中两个字符串之间的区别 [关闭]
【发布时间】:2015-04-11 03:19:24
【问题描述】:

请正则表达式专家帮忙看看这个问题是否可以通过正则表达式解决:

给定字符串 1 是任意字符串

字符串 2 是包含字符串 1 的所有部分的任何字符串(但不是简单的匹配——我会举个例子)

如何使用正则表达式将字符串 2 中的字符串 1 的所有部分替换为空白,以便剩下的字符串不在字符串 1 中?

例如: str1 = "测试 xyz"; str2 = "测试 ab xyz"

我想要“ab”或“ab”回来。我可以编写什么正则表达式,这样当我在 str2 上运行替换函数时,它将返回“ab”?

这是一些非正则表达式代码:

            function findStringDiff(str1, str2) {
                var compareString = function(str1, str2) {
                    var a1 = str1.split("");
                    var a2 = str2.split("");
                    var idx2 = 0;
                    a1.forEach(function(val) {
                        if (a2[idx2] === val) {
                          a2.splice(idx2,1);
                        } else {
                            idx2 += 1;
                        }
                    });
                    if (idx2 > 0) {
                        a2.splice(idx2,a2.length);
                    }
                    return a2.join("");
                }

                if (str1.length < str2.length) {
                    return compareString(str1, str2);
                } else {
                    return compareString(str2, str1);
                }
            }

            console.log(findStringDiff("test xyz","test ab xyz"));

【问题讨论】:

  • 我看不出正则表达式在这里有什么帮助。
  • 顺便说一句,你在这里展示的算法会让'$1.00''00.1$'之间看起来没有区别。
  • 上面的代码甚至认为“ab”和“cd”是一样的。
  • 预期输出是什么?
  • 你能举出多个例子,不仅仅是一个字符的区别吗?目前还不清楚你想要什么。

标签: javascript regex


【解决方案1】:

正则表达式仅识别字符串是否与特定模式匹配。它们不够灵活,无法像您要求的那样进行比较。您必须获取第一个字符串并基于它构建一个常规语言来识别第二个字符串,然后使用匹配组来抓取第二个字符串的其他部分并将它们连接在一起。这是我认为你想要的东西以一种可读的方式。

//assuming "b" contains a subsequence containing 
//all of the letters in "a" in the same order
function getDifference(a, b)
{
    var i = 0;
    var j = 0;
    var result = "";

    while (j < b.length)
    {
        if (a[i] != b[j] || i == a.length)
            result += b[j];
        else
            i++;
        j++;
    }
    return result;
}

console.log(getDifference("test fly", "test xy flry"));

这是一个 jsfiddle:http://jsfiddle.net/d4rcuxw9/1/

【讨论】:

  • 我明白了。 j 是 b 的索引,i 是 a 的索引。您正在遍历较长的字符串并将“未找到/不同”字符存储在结果中。我喜欢。由于无法使用正则表达式,因此我将其标记为我的首选答案。谢谢米莉!
  • 我知道我来得太晚了,这个问题已经结束了,但以防万一有人想找出两个字符串之间的区别而不管字符的顺序:jsfiddle.net/c8xchkxq
  • 不错的简单解决方案,谢谢!我需要在单词级别上相同,并且还想接收添加单词的位置。如果其他人有兴趣,请参阅:jsfiddle.net/409doc37
【解决方案2】:

我觉得这个问题很有趣。尽管我有点晚了,但我想分享我的解决方案,了解如何使用正则表达式完成此任务。解决方案简洁但可读性不强。

虽然我喜欢它的简洁性,但我可能不会在我的代码中使用它,因为它的不透明性降低了可维护性。

var str1 = "test xyz",
    str2 = "test ab xyz"
    replacement = '';
var regex = new RegExp(str1.split('').map(function(char){
    return char.replace(/[.(){}+*?[|\]\\^$]/, '\\$&');
}).join('(.*)'));
if(regex.test(str2)){
    for(i=1; i<str1.length; i++) replacement = replacement.concat('$' + i);
    var difference = str2.replace(regex, replacement);
} else {
    alert ('str2 does not contain str1');
}

"test xyz" 的正则表达式是 /t(.*)e(.*)s(.*)t(.*) (.*)x(.*)y(.*)z/replacement"$1$2$3$4$5$6$7"

代码不再简洁,但现在即使 str1 包含特殊字符也可以使用。

【讨论】:

  • 我首先认为 str1 限制为 10 个字符。但我刚刚了解到 Javascript 允许反向引用大于 9 的数字。
  • 这找不到test xyz vs test xytest{2 spaces}xyz vs test xyz 之间的区别。
  • @LorenzMeyer 我很兴奋。我认为你正在做某事。但是当我使用 var str1 = "$1.00", str2 = "$1..00" 时,它没有找到点。我希望你能想出一个健壮的解决方案——这样你就可以根据 str1 输入动态构建正则表达式,这很有趣......
  • 是的,它没有找到点,因为点是正则表达式中的特殊字符。它不适用于(){}+*\[]neither。对于一个健壮的解决方案,我们需要转义所有这些特殊字符。
  • @LorenzMeyer 您的意思是您更新了代码以处理点或美元符号等特殊字符吗?我尝试了点和美元符号,但代码不起作用。 jsfiddle.net/mnzhbz7o
【解决方案3】:

找出是否有多余的'.'就像您要求的那样,您可以这样做:

result = "$1...00".match(/\$1\.(\.*)?00/)[1];

result 然后是 EXTRA '.'。您不能使用正则表达式来仅使用正则表达式来比较字符串。也许用这个,然后比较结果。

你也可以试试这个:

result = "$1...00".match(/(\$)(\d+)\.(\.*)?(\d+)/);
// Outputs: ["$1...00", "$", "1", "..", "00"]

这将提取各个部分进行比较。

【讨论】:

    【解决方案4】:

    如果您只关心测试给定字符串是否包含两个或多个连续点 '.'字符:

    var string = '$1..00',
        regexp = /(\.\.+)/;
    
    alert('Is this regular expression ' + regexp + ' found in this string ' + string + '?\n\n' + regexp.test(string) + '\n\n' + 'Match and captures: ' + regexp.exec(string));

    如果需要匹配货币格式:

    var string = '$1..00',
        regexp = /\$\d*(\.\.+)(?:\d\d)+/;
    
    alert('Is this regular expression ' + regexp + ' found in this string ' + string + '?\n\n' + regexp.test(string) + '\n\n' + 'Match and captures: ' + regexp.exec(string));

    但我提醒您,正则表达式不是用于比较两个字符串之间的差异;而是用于比较两个字符串之间的差异。它们用于定义模式以匹配给定的字符串。

    所以,虽然这可以直接回答如何找到“多点”模式,但对于“找出两个字符串之间的差异”是没有用的。

    StackOverflow 标签 wiki 为 RegEx 提供了出色的概述和基本参考。见:https://stackoverflow.com/tags/regex/info

    【讨论】:

    • 问题是关于比较两个字符串,而不仅仅是删除一个字符串。
    • @LorenzMeyer 见上文我解释过的地方:'但我提醒你,正则表达式不是用于比较两个字符串之间的差异;它们用于定义模式以匹配给定的字符串。因此,虽然这可以直接回答如何找到“多点”模式,但对于“找出两个字符串之间的差异”是没有用的。'
    • @LorenzMeyer 还请注意我在上述 OP 问题上的早期 cmets,其中还值得注意的是,该问题已多次改进,在此期间坚持使用专门针对“多点”模式的 RegEx 解决方案被传达。这个问题后来因为不清楚而被搁置。
    • @LorenzMeyer 最后,请参阅When should I vote down?,其中指示人们“在遇到极其草率、不费吹灰之力的帖子或明显且可能危险地不正确的答案时,请使用您的反对票。 "考虑到这是一项善意的努力,可以为 OP 的不清楚的问题中的一个特别要求的部分提供一个有效的解决方案,并给出明确的解释,我很惊讶你发现它非常草率、不费吹灰之力,而且可能是危险的不正确。
    • @gfullam 我试图投票,但我没有足够的声誉:) 但是,我的问题一直是使用正则表达式来查找两个字符串的差异——它在标题中。我给出的第一个例子是关于 str1="$1.00" 而 str2="$1..00"。所以我认为这就是混乱。寻找双。很简单,但我从第一天开始真正感兴趣的是如何在 1..0 美元内替换 1.00 美元,这样只有 .离开了。我也因为提出问题而投了反对票——我真的不怎么想:)而且我知道你正在努力提供帮助。谢谢!
    猜你喜欢
    • 2012-05-19
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 2013-09-24
    • 2022-01-18
    • 2012-05-27
    相关资源
    最近更新 更多