正则表达式比较字符串,看看差异在哪里
我正在创建一个正则表达式,以查看所有文档顶部的版权信息是否格式正确。
版权很长,因此我的正则表达也很长。
让我们说版权信息如下:
/*///////////////////////////////////////////////////////////////////////// Copyright content which is a lot goes in here. Programmer: Tono Nam /////////////////////////////////////////////////////////////////////////*/
然后我将使用正则表达式:
var pattern = @"/\*///////////////////////////////////////////////////////////////////////// Copyright content which is a lot goes in here. Programmer: (?[\w '\.]+) /////////////////////////////////////////////////////////////////////////\*/";
如果我将正则表达式应用于第一个文本,它将给我一个匹配,一切都很棒。 问题是当正则表达式不匹配时让我们说程序员在顶部放置一个额外的/
。 我的正则表达式将不再匹配。 通过这个例子很容易注意到,但真正的版权要长得多,知道错误在哪里会很好。 或者有时会出现错误的错误。 例如,您可能会遇到Programer而不是Programmer。 正因为如此,我将不得不调查整个版权并尝试发现错误。 我认为应该有一种更简单的方法来做我需要的事情
编辑
如果主题恰好是:
/ * //////////////////////////////////////////////// /////////////////////////
这里的版权内容很多SOME_MISPELED_WORD。
程序员:Tono Nam
////////////////////////////////////////////////// /////////////////////// * /
由于SOME_MISPELED_WORD
,正则表达式将不匹配因此我想知道发生错误的索引,以便我可以查看:
/ * //////////////////////////////////////////////// /////////////////////////
这里有很多版权内容<————–这里
而不是整个事情。
另一个例子是版权信息是:
/ * //////////////////////////////////////////////// /////////////////////////
版权内容很多就在这里。
程序员:Tono Nam
////////////////////////////////////////////////// //////////////////////// * /
我想在最后一行得到一个错误,因为有一个额外的/
。
我认为正如你所拥有的正则表达式太严格了。 尝试更像以下内容:
@"^/\*(/*)(.*)(Programmer:|Programer:){1}(\d*)(){1}(/*)\*/$"
这将确保您处于注释区块中,它可以在开头和结尾处包含任意数量的正斜杠,并且不会限制输入版权声明的能力,同时仍然确保程序员已正确签名。 虽然老实说我认为试图在正则表达式中强制执行程序员名称会让你在长期内遇到更多的麻烦。 我建议将其拉出来,然后检查程序员“部分”是否存在。
最后我有解决方案:
基本上我们想知道正则表达式失败的地方。 如果我们在哪里有不变的字符串,我们将能够比较它们并查看它不同的字符。 换句话说,如果我在哪里:
var a = "12345"; var b = "1234A";
那么我们可以比较a[0]
和b[0]
然后a[1]
和b[1]
直到我们有差异。
所以,让我们这样做!
假设我们的版权必须如下:
/*///// Copyright content which is a lot goes in here. Programmer:Tono Nam Description:This is the description of the file.... /////*/
让我们删除所有可能变化的东西,以便我们可以应用我们的第一个例子:
/*///// Copyright content which is a lot goes in here. Programmer: Description: /////*/
然后唯一复杂的是创建一个正则表达式,它将删除所有可能变化的东西,以便最终得到该字符串。 所以模式将是:
var regexPattern = @"(?s)(/\*/*.+Programmer:)(?[^\r\n]*?)(\r.*Description:)(?[^\r\n]*)(\r.*?/*\*/)";
有了这种模式,我们将能够转向:
/*///// Copyright content which is a lot goes in here. Programmer:Tono Nam bla bla bla Description:THIS IS A DIFFERENT DESCRIPTION /////*/
INTO
/*///// Copyright content which is a lot goes in here. Programmer: Description: /////*/
现在我们有两个字符串来比较!
这是我刚才解释的代码
// the subject we want to test var subject = @"/*///// Copyright content which is a lot goes in here. Programmer:Tono Nam Description:This is the description of the file.... /////*/"; // the actual pattern this should be a readonly constant type on a real program cause it never should change var pattern = @"/*///// Copyright content which is a lot goes in here. Programmer: Description: /////*/"; // we use this pattern to turn the first subject into the second if we can var regexPattern = @"(?s)(/\*/*.+Programmer:)(?[^\r\n]*?)(\r.*Description:)(?[^\r\n]*)(\r.*?/*\*/)"; // note $1 means group 1 so here we are basically removing the groups name and desc var newSubject = Regex.Replace(subject, regexPattern, "$1$2$3"); // at this point if newSubject = pattern we know that the header is formatted correctly! // Let's see where they are different! for (int i = 0; i < pattern.Length; i++) { if (pattern[i] != newSubject[i]) { throw new Exception("There is a problem at index " + i); } }
在这个例子中它应该工作,因为我的主题正确格式化。 但是如果我在乞讨时多加一点/那么看看会发生什么:(我突出显示6 /
字符应该是5
试试这个正则Regex
:
/\*/{2,}(?:\n|.)*(?:Programm?er\s*:\s*(?.+))[\n\r\s]*(?:Description\s*:\s*(?.+))?
并获得名为programmer
和description
。 这适用于所有上述条件。