I am looking at http://code.google.com/p/google-diff-match-patch/ and have downloaded the file. When I look at it is 2 files
DiffMatchPatch.cs
DiffMatchPatchTest.cs
When I try to make a new object of DiffMatchPatch.cs I have to pass in some operation and string text.
http://neil.fraser.name/software/diff_match_patch/svn/trunk/demos/demo_diff.html
In the demo they cross out the words that are different and that is what I am trying to achieve.
I am trying to compare 2 blocks of text on the server side finds the differences and send a email to the user with the file block of text to them like the end result is in the demo that I posted above.
So does anyone have a tutorial on how to use the C# version?
For reference, this is really easy:
var dmp = new diff_match_patch();
var diffs = dmp.diff_main(text1, text2);
var html = dmp.diff_prettyHtml(diffs);
Implementation with current version(2.1.0) would look like this
var dmp = DiffMatchPatchModule.Default;
var diffs = dmp.DiffMain(text1, text2);
var html = dmp.DiffPrettyHtml(diffs);
For anyone who came across this thread because of the title and expected an explanation on how to use the Google Diff-Match-Patch algorithm via the https://github.com/pocketberserker/Diff.Match.Patch library found on NuGet, to create a diff string, so he can send the change somewhere (e.g. via websocket) and restore it at the destination based on the old value and the diff string, that would work like this:
var oldValue = "Test old text.";
var newValue = "Test new text.";
// create diff string
var dmp = DiffMatchPatch.DiffMatchPatchModule.Default;
var diffs = dmp.DiffMain(oldValue, newValue);
var srcDelta = dmp.DiffToDelta(diffs);
// restore from diff
var dmp = DiffMatchPatch.DiffMatchPatchModule.Default;
var dstDelta = dmp.DiffFromDelta(oldValue, srcDelta);
var restoredNewValue = dmp.DiffText2(dstDelta);
Related
I am most familiar with PowerShell and have recently moved into using C# as my primary language. In PowerShell it's possible to do the following
$var1 = "abc"
"abc" -match "$var1"
This results in a true statement.
I would like to do be able to do the same thing in C#. I know that you can use interpolation with C# and I have tries various ways of trying to use Regex.Match() with no luck.
Example:
string toMatch = "abc";
var result = Regex.Match("abc", $"{{toMatch}}");
var a = Regex.Match("abc", $"{{{toMatch}}}");
var b = Regex.Match("abc", $"{toMatch}");
var c = Regex.Match(toMatch,toMatch);
None of the above seems to work. I am not even sure if what I am trying to do is possible in C#. Ideally I'd like to be able to use a combination of variables and Regex for a match. Something even like this Regex.Match(varToMatch,$"{{myVar}}\\d+\\w{4}")
edit:
After reading some answers here and trying some code out it appears that my real issue is trying to match up against a directory path. Something like "C:\temp\abcfile". For example:
string path = #"C:\temp\abc";
string path2 = #"C:\temp\abc";
string fn = path.Split('\\').LastOrDefault();
path = Regex.Escape(path);
path2 = Regex.Escape(path2);
Regex rx = new Regex(path);
var a = Regex.Match(path.Split('\\').Last().ToString(), $"{fn}");
//Example A works if I split and match on just the file name.
var b = Regex.Match(path, $"{rx}");
//Example B does not work, even though it's a regex object.
var c = Regex.Match(path, $"{{path}}");
//Example C I've tried one, two, and three sets of parenthesis with no luck
var d = Regex.Match(path,path);
// Even a direct variable to variable match returns 0 results.
You seem to have it right in the last example, so perhaps the issue is that you're expecting a bool result instead of a Match result?
Hopefully this small example helps:
int a = 123;
string b = "abc";
string toMatch = "123 and abc";
var result = Regex.Match(toMatch, $"{a}.*{b}");
if (result.Success)
{
Console.WriteLine("Found a match!");
}
I have a string "(zoneId==176)&&((startTime==100)&&(endTime==1200))" from which i want to fetch the value of startTime and endTime in C#. How to do this i am new to c# programming that why i need some clue
That doesn't look like a String but a block of code. Assuming that is the value entered into your code, you could do the following:
var input = "(zoneId==176)&&((startTime==100)&&(endTime==1200))";
var time = input.Split(')');
var start = time.FirstOrDefault(s => s.Contains("startTime")).Split('=')[2];
var end = time.FirstOrDefault(e => e.Contains("endTime")).Split('=')[2];
Your output would be as follows: 100 and 1200
The above implementation works, but shouldn't be used for production purposes for an assortment of reasons. You'll want to focus on:
Substring
Split
Remove
Regular Expressions
These are all essential to learning how to parse data and or any other form of string manipulation. Hopefully this points you in the proper direction.
Another approach would be:
var input = "(zoneId==176)&&((startTime==100)&&(endTime==1200))";
var section = input.Split('=');
foreach(var region in section)
{
var zone = region.Substring(0, region.Length);
var number = zone.Where(d => char.IsDigit(d)).ToArray();
}
How can I find what line number in the source file the declaration was found on?
Disclaimer: I work for Microsoft on the Roslyn team.
You can use the ISyntaxTree.GetLineSpan() method to convert to a line number. For example, given an ISymbol "symbol", you can get the start location of the first definition with:
var loc = symbol.Locations.First();
var lineSpan = loc.SourceTree.GetLineSpan(loc.SourceSpan,
usePreprocessorDirectives: false);
var line = lineSpan.StartLinePosition.Line;
var character = lineSpan.StartLinePosition.Character;
From the title, it looks like you're starting with a SyntaxNode, so you can just use the Span property directly.
I am reading from history, and I want that when i come across a google query, I can extract the query string. I am not using request or httputility since i am simply parsing a string. however, when i come across URLs like this, my program fails to parse it properly:
http://www.google.com.mt/search?client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&channel=s&hl=mt&source=hp&biw=986&bih=663&q=hotmail&meta=&btnG=Fittex+bil-Google
what i was trying to do is get the index of q= and the index of & and take the words in between but in this case the index of & will be smaller than q= and it will give me errors.
any suggestions?
thanks for your answers, all seem good :) p.s. i couldn't use httputility, not I don't want to. when i add a reference to system.web, httputility isn't included! it's only included in an asp.net application. Thanks again
It's not clear why you don't want to use HttpUtility. You could always add a reference to System.Web and use it:
var parsedQuery = HttpUtility.ParseQueryString(input);
Console.WriteLine(parsedQuery["q"]);
If that's not an option then perhaps this approach will help:
var query = input.Split('&')
.Single(s => s.StartsWith("q="))
.Substring(2);
Console.WriteLine(query);
It splits on & and looks for the single split result that begins with "q=" and takes the substring at position 2 to return everything after the = sign. The assumption is that there will be a single match, which seems reasonable for this case, otherwise an exception will be thrown. If that's not the case then replace Single with Where, loop over the results and perform the same substring operation in the loop.
EDIT: to cover the scenario mentioned in the comments this updated version can be used:
int index = input.IndexOf('?');
var query = input.Substring(index + 1)
.Split('&')
.SingleOrDefault(s => s.StartsWith("q="));
if (query != null)
Console.WriteLine(query.Substring(2));
If you don't want to use System.Web.HttpUtility (thus be able to use the client profile), you can still use Mono HttpUtility.cs which is only an independent .cs file that you can embed in your application. Then you can simply use the ParseQueryString method inside the class to parse the query string properly.
here is the solution -
string GetQueryString(string url, string key)
{
string query_string = string.Empty;
var uri = new Uri(url);
var newQueryString = HttpUtility.ParseQueryString(uri.Query);
query_string = newQueryString[key].ToString();
return query_string;
}
Why don't you create a code which returns the string from the q= onwards till the next &?
For example:
string s = historyString.Substring(url.IndexOf("q="));
int newIndex = s.IndexOf("&");
string newString = s.Substring(0, newIndex);
Cheers
Use the tools available:
String UrlStr = "http://www.google.com.mt/search?client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&channel=s&hl=mt&source=hp&biw=986&bih=663&q=hotmail&meta=&btnG=Fittex+bil-Google";
NameValueCollection Items = HttpUtility.ParseQueryString(UrlStr);
String QValue = Items["q"];
If you really need to do the parsing yourself, and are only interested in the value for 'q' then the following would work:
string url = #"http://www.google.com.mt/search?" +
"client=firefoxa&rls=org.mozilla%3Aen-" +
"US%3Aofficial&channel=s&hl=mt&source=hp&" +
"biw=986&bih=663&q=hotmail&meta=&btnG=Fittex+bil-Google";
int question = url.IndexOf("?");
if(question>-1)
{
int qindex = url.IndexOf("q=", question);
if (qindex > -1)
{
int ampersand = url.IndexOf('&', qindex);
string token = null;
if (ampersand > -1)
token = url.Substring(qindex+2, ampersand - qindex - 2);
else
token = url.Substring(qindex+2);
Console.WriteLine(token);
}
}
But do try to look at using a proper URL parser, it will save you a lot of hassle in the future.
(amended this question to include a check for the '?' token, and support 'q' values at the end of the query string (without the '&' at the end) )
And that's why you should use Uri and HttpUtility.ParseQueryString.
HttpUtility is fine for the .Net Framework. However that class is not available for WinRT apps. If you want to get the parameters from a url in a Windows Store App you need to use WwwFromUrlDecoder. You create an object from this class with the query string you want to get the parameters from, the object has an enumerator and supports also lambda expressions.
Here's an example
var stringUrl = "http://localhost/?name=Jonathan&lastName=Morales";
var decoder = new WwwFormUrlDecoder(stringUrl);
//Using GetFirstByName method
string nameValue = decoder.GetFirstByName("name");
//nameValue has "Jonathan"
//Using Lambda Expressions
var parameter = decoder.FirstOrDefault(p => p.Name.Contains("last")); //IWwwFormUrlDecoderEntry variable type
string parameterName = parameter.Name; //lastName
string parameterValue = parameter.Value; //Morales
You can also see http://www.dzhang.com/blog/2012/08/21/parsing-uri-query-strings-in-windows-8-metro-style-apps
I guess I need some regex help. I want to find all tags like <?abc?> so that I can replace it with whatever the results are for the code ran inside. I just need help regexing the tag/code string, not parsing the code inside :p.
<b><?abc print 'test' ?></b> would result in <b>test</b>
Edit: Not specifically but in general, matching (<?[chars] (code group) ?>)
This will build up a new copy of the string source, replacing <?abc code?> with the result of process(code)
Regex abcTagRegex = new Regex(#"\<\?abc(?<code>.*?)\?>");
StringBuilder newSource = new StringBuilder();
int curPos = 0;
foreach (Match abcTagMatch in abcTagRegex.Matches(source)) {
string code = abcTagMatch.Groups["code"].Value;
string result = process(code);
newSource.Append(source.Substring(curPos, abcTagMatch.Index));
newSource.Append(result);
curPos = abcTagMatch.Index + abcTagMatch.Length;
}
newSource.Append(source.Substring(curPos));
source = newSource.ToString();
N.B. I've not been able to test this code, so some of the functions may be slightly the wrong name, or there may be some off-by-one errors.
var new Regex(#"<\?(\w+) (\w+) (.+?)\?>")
This will take this source
<b><?abc print 'test' ?></b>
and break it up like this:
Value: <?abc print 'test' ?>
SubMatch: abc
SubMatch: print
SubMatch: 'test'
These can then be sent to a method that can handle it differently depending on what the parts are.
If you need more advanced syntax handling you need to go beyond regex I believe.
I designed a template engine using Antlr but thats way more complex ;)
exp = new Regex(#"<\?abc print'(.+)' \?>");
str = exp.Replace(str, "$1")
Something like this should do the trick. Change the regexes how you see fit