Find all occurrences of substring in string - c#

I have a text file that includes things such as the following:
_vehicle_12 = objNull;
if (true) then
{
_this = createVehicle ["Land_Mil_Guardhouse", [13741.654, 2926.7075, 3.8146973e-006], [], 0, "CAN_COLLIDE"];
_vehicle_12 = _this;
_this setDir -92.635818;
_this setPos [13741.654, 2926.7075, 3.8146973e-006];
};
I want to find all occurrences between { and }; and assign the following strings:
string direction = "_this setDir" value, in example _vehicle_12 it would mean that:
string direction = "-92.635818";
string position = "_this setPos" value, in example _vehicle_12 it would be:
string position = "[13741.654, 2926.7075, 3.8146973e-006]";
I have multiple occurrences of these types and would like to figure out the best way each time the { }; occurs to set direction and position and move onto the next occurrence.
The following code can read the string (that holds the file in a large string) and it finds the first occurence fine, however I would like to adapt it to finding every occurrence of the { and };
string alltext = File.ReadAllText(#file);
string re1 = ".*?"; // Non-greedy match on filler
string re2 = "(\\{.*?\\})"; // Curly Braces 1
Regex r = new Regex(re1 + re2, RegexOptions.IgnoreCase | RegexOptions.Singleline);
Match m = r.Match(alltext);
if (m.Success)
{
String cbraces1 = m.Groups[1].ToString();
MessageBox.Show("Found vehicle: " + cbraces1.ToString() + "\n");
}

Think of a regex that might work
Test it.
If it does not work, modify and return to step 2.
You have a working regex :-)
To get you started:
\{\n([0-z\[\]" ,-\.=]+;\n)+\}
should return the individual lines inside the curly braces.

Related

How to pass the second occurrence of a blankspace in regex?

Duration : 00:05:48.73
File Size 61.5M
As you can see the two lines. One of them has a : separating the word and the number, the other one has a blankspace separating the word and number.
I need to separate the word from the number for both the cases (for : as well as for blankspace).
I used String.Split(':') and String.Split(null). While the String.Split(':') worked, and there were only two items in the array, String.Split(null) resulted in the following items in the array: File, Size, 61.5M. So three items. I want to make that into two.
this is the code I'm using:
private static Regex _regex = new Regex(#"^([\p{L}_ ]+):?(.+)$");
Match match = _regex.Match(line);
if (match.Success)
{
string key = match.Groups[1].Captures[0].Value;
string value = match.Groups[2].Captures[0].Value;
}
your split may not work, but if you use the regex you mentioned that should work fine.
Please find the attached fiddle. https://dotnetfiddle.net/g0apnE
var line1 = "Duration : 00:05:48.73";
var line2 = "File Size 61.5M";
Regex _regex = new Regex(#"^([\p{L}_ ]+):?(.+)$");
Match match = _regex.Match(line1);
if (match.Success)
{
string key = match.Groups[1].Captures[0].Value;
string value = match.Groups[2].Captures[0].Value;
//call trim to remove extra space around.
Console.WriteLine(key.Trim()); //Duration
Console.WriteLine(value.Trim()); //00:05:48.73
}
match = _regex.Match(line2);
if (match.Success)
{
string key = match.Groups[1].Captures[0].Value;
string value = match.Groups[2].Captures[0].Value;
//call trim to remove extra space around.
Console.WriteLine(key.Trim()); //File Size
Console.WriteLine(value.Trim()); //61.5M
}

C# Regex returning multiple lines of text

I have the following function:
public static string ReturnEmailAddresses(string input)
{
string regex1 = #"\[url=";
string regex2 = #"mailto:([^\?]*)";
string regex3 = #".*?";
string regex4 = #"\[\/url\]";
Regex r = new Regex(regex1 + regex2 + regex3 + regex4, RegexOptions.IgnoreCase | RegexOptions.Multiline);
MatchCollection m = r.Matches(input);
if (m.Count > 0)
{
StringBuilder sb = new StringBuilder();
int i = 0;
foreach (var match in m)
{
if (i > 0)
sb.Append(Environment.NewLine);
string shtml = match.ToString();
var innerString = shtml.Substring(shtml.IndexOf("]") + 1, shtml.IndexOf("[/url]") - shtml.IndexOf("]") - 1);
sb.Append(innerString); //just titles
i++;
}
return sb.ToString();
}
return string.Empty;
}
As you can see I define a url in the "markdown" format:
[url = http://sample.com]sample.com[/url]
In the same way, emails are written in that format too:
[url=mailto:service#paypal.com.au]service#paypal.com.au[/url]
However when i pass in a multiline string, with multiple email addresses, it only returns the first email only. I would like it to have multple matches, but I cannot seem to get that working?
For example
[url=mailto:service#paypal.com.au]service#paypal.com.au[/url] /r/n a whole bunch of text here /r/n more stuff here [url=mailto:anotheremail#paypal.com.au]anotheremail#paypal.com.au[/url]
This will only return the first email above?
The mailto:([^\?]*) part of your pattern is matching everything in your input string. You need to add the closing bracket ] to the inside of your excluded characters to restrict that portion from overflowing outside of the "mailto" section and into the text within the "url" tags:
\[url=mailto:([^\?\]]*).*?\[\/url\]
See this link for an example: https://regex101.com/r/zcgeW8/1
You can extract desired result with help of positive lookahead and positive lookbehind. See http://www.rexegg.com/regex-lookarounds.html
Try regex: (?<=\[url=mailto:).*?(?=\])
Above regex will capture two email addresses from sample string
[url=mailto:service#paypal.com.au]service#paypal.com.au[/url] /r/n a whole bunch of text here /r/n more stuff here [url=mailto:anotheremail#paypal.com.au]anotheremail#paypal.com.au[/url]
Result:
service#paypal.com.au
anotheremail#paypal.com.au

How to replace the text between two characters in c#

I am bit confused writing the regex for finding the Text between the two delimiters { } and replace the text with another text in c#,how to replace?
I tried this.
StreamReader sr = new StreamReader(#"C:abc.txt");
string line;
line = sr.ReadLine();
while (line != null)
{
if (line.StartsWith("<"))
{
if (line.IndexOf('{') == 29)
{
string s = line;
int start = s.IndexOf("{");
int end = s.IndexOf("}");
string result = s.Substring(start+1, end - start - 1);
}
}
//write the lie to console window
Console.Write Line(line);
//Read the next line
line = sr.ReadLine();
}
//close the file
sr.Close();
Console.ReadLine();
I want replace the found text(result) with another text.
Use Regex with pattern: \{([^\}]+)\}
Regex yourRegex = new Regex(#"\{([^\}]+)\}");
string result = yourRegex.Replace(yourString, "anyReplacement");
string s = "data{value here} data";
int start = s.IndexOf("{");
int end = s.IndexOf("}", start);
string result = s.Substring(start+1, end - start - 1);
s = s.Replace(result, "your replacement value");
To get the string between the parentheses to be replaced, use the Regex pattern
string errString = "This {match here} uses 3 other {match here} to {match here} the {match here}ation";
string toReplace = Regex.Match(errString, #"\{([^\}]+)\}").Groups[1].Value;
Console.WriteLine(toReplace); // prints 'match here'
To then replace the text found you can simply use the Replace method as follows:
string correctString = errString.Replace(toReplace, "document");
Explanation of the Regex pattern:
\{ # Escaped curly parentheses, means "starts with a '{' character"
( # Parentheses in a regex mean "put (capture) the stuff
# in between into the Groups array"
[^}] # Any character that is not a '}' character
* # Zero or more occurrences of the aforementioned "non '}' char"
) # Close the capturing group
\} # "Ends with a '}' character"
The following regular expression will match the criteria you specified:
string pattern = #"^(\<.{27})(\{[^}]*\})(.*)";
The following would perform a replace:
string result = Regex.Replace(input, pattern, "$1 REPLACE $3");
For the input: "<012345678901234567890123456{sdfsdfsdf}sadfsdf" this gives the output "<012345678901234567890123456 REPLACE sadfsdf"
You need two calls to Substring(), rather than one: One to get textBefore, the other to get textAfter, and then you concatenate those with your replacement.
int start = s.IndexOf("{");
int end = s.IndexOf("}");
//I skip the check that end is valid too avoid clutter
string textBefore = s.Substring(0, start);
string textAfter = s.Substring(end+1);
string replacedText = textBefore + newText + textAfter;
If you want to keep the braces, you need a small adjustment:
int start = s.IndexOf("{");
int end = s.IndexOf("}");
string textBefore = s.Substring(0, start-1);
string textAfter = s.Substring(end);
string replacedText = textBefore + newText + textAfter;
the simplest way is to use split method if you want to avoid any regex .. this is an aproach :
string s = "sometext {getthis}";
string result= s.Split(new char[] { '{', '}' })[1];
You can use the Regex expression that some others have already posted, or you can use a more advanced Regex that uses balancing groups to make sure the opening { is balanced by a closing }.
That expression is then (?<BRACE>\{)([^\}]*)(?<-BRACE>\})
You can test this expression online at RegexHero.
You simply match your input string with this Regex pattern, then use the replace methods of Regex, for instance:
var result = Regex.Replace(input, "(?<BRACE>\{)([^\}]*)(?<-BRACE>\})", textToReplaceWith);
For more C# Regex Replace examples, see http://www.dotnetperls.com/regex-replace.

Get partial string from string

I have the following string:
This isMyTest testing
I want to get isMyTest as a result. I only have two first characters available("is"). The rest of the word can vary.
Basically, I need to select a first word delimeted by spaces which starts with chk.
I've started with the following:
if (text.contains(" is"))
{
text.LastIndexOf(" is"); //Should give me index.
}
now I cannot find the right bound of the word since I need to match on something like
You can use regular expressions:
string pattern = #"\bis";
string input = "This isMyTest testing";
return Regex.Matches(input, pattern);
You can use IndexOf to get the index of the next space:
int startPosition = text.LastIndexOf(" is");
if (startPosition != -1)
{
int endPosition = text.IndexOf(' ', startPosition + 1); // Find next space
if (endPosition == -1)
endPosition = text.Length - 1; // Select end if this is the last word?
}
What about using a regex match? Generally if you are searching for a pattern in a string (ie starting with a space followed by some other character) regex are perfectly suited to this. Regex statements really only fall apart in contextually sensitive areas (such as HTML) but are perfect for a regular string search.
// First we see the input string.
string input = "/content/alternate-1.aspx";
// Here we call Regex.Match.
Match match = Regex.Match(input, #"[ ]is[A-z0-9]*", RegexOptions.IgnoreCase);
// Here we check the Match instance.
if (match.Success)
{
// Finally, we get the Group value and display it.
string key = match.Groups[1].Value;
Console.WriteLine(key);
}

Search string pattern

If I have a string like MCCORMIC 3H R Final 08-26-2011.dwg or even MCCORMIC SMITH 2N L Final 08-26-2011.dwg and I wanted to capture the R in the first string or the L in the second string in a variable, what is the best method for doing so? I was thinking about trying the below statement but it does not work.
string filename = "MCCORMIC 3H R Final 08-26-2011.dwg"
string WhichArea = "";
int WhichIndex = 0;
WhichIndex = filename.IndexOf("Final");
WhichArea = filename.Substring(WhichIndex - 1,1); //Trying to get the R in front of word Final
Just split by space:
var parts = filename.Split(new [] {' '},
StringSplitOptions.RemoveEmptyEntries);
WhichArea = parts[parts.Length - 3];
It looks like the file names have a very specific format, so this will work just fine.
Even with any number of spaces, using StringSplitOptions.RemoveEmptyEntries means spaces will not be part of the split result set.
Code updated to deal with both examples - thanks Nikola.
I had to do something similar, but with Mirostation drawings instead of Autocad. I used regex in my case. Here's what I did, just in case you feel like making it more complex.
string filename = "MCCORMIC 3H R Final 08-26-2011.dwg";
string filename2 = "MCCORMIC SMITH 2N L Final 08-26-2011.dwg";
Console.WriteLine(TheMatch(filename));
Console.WriteLine(TheMatch(filename2));
public string TheMatch(string filename) {
Regex reg = new Regex(#"[A-Za-z0-9]*\s*([A-Z])\s*Final .*\.dwg");
Match match = reg.Match(filename);
if(match.Success) {
return match.Groups[1].Value;
}
return String.Empty;
}
I don't think Oded's answer covers all cases. The first example has two words before the wanted letter, and the second one has three words before it.
My opinion is that the best way to get this letter is by using RegEx, assuming that the word Final always comes after the letter itself, separated by any number of spaces.
Here's the RegEx code:
using System.Text.RegularExpressions;
private string GetLetter(string fileName)
{
string pattern = "\S(?=\s*?Final)";
Match match = Regex.Match(fileName, pattern);
return match.Value;
}
And here's the explanation of RegEx pattern:
\S(?=\s*?Final)
\S // Anything other than whitespace
(?=\s*?Final) // Positive look-ahead
\s*? // Whitespace, unlimited number of repetitions, as few as possible.
Final // Exact text.

Categories

Resources