I found this answer for my question, but it for PHP. Perhaps there is an analogue for .NET? I know about Split method, but I don't understand how to save text outside my tags <#any_text#>, and I need a regular expression (by the condition of the task).
For example:
string: aaa<#bbb#>aaa<#bb#>c
list: aaa
<#bbb#>
aaa
<#bb#>
c
Here you have passing test. It wasn't hard to find it on web and it would be definitely faster and better for you - try first finding solution yourself, trying some code, and then ask a question. This way you will actually learn something.
[TestMethod]
public void TestMethod1()
{
string source = "aaa<#bbb#>aaa<#bb#>c";
Regex r = new Regex("(<#.+?#>)");
string[] result = r.Split(source);
Assert.AreEqual(5, result.Length);
}
string input = #"aaa<#bbb#>aaa<#bb#>c";
var list = Regex.Matches(input, #"\<.+?\>|[^\<].+?[^\>]|.+?")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
Related
I have a string that always takes a general form. I wish to extract information from it and place it in an array.
Given the following input:
John Doe +22\r\nPong
I want the following output
John Doe
+22
Pong
I'm using the following bit of code to extract the details I want.
public static string[] DetailExtractor(string input)
{
return Regex.Matches(input, #"(.*(?=\s\+))|(\+\d{1,2}(?=\\r\\n))|((?<=\\r\\n).*)")
.OfType<Match>()
.Select(m => m.Value)
.ToArray();
}
But it gives me the following output:
Player Name
""
However, using the same regex expression in this online regex tester matches all the elements I want.
Why does it work for one and not the other? Does Regex.Matches not work the way I think it does?
Just taking a guess here, but I'm betting that you are using the following:
var details = DetailExtractor("John Doe +22\r\nPong");
The above would convert \r\n to the a carriage return and a new line character. This would prevent the regex you wrote from working. Instead you can specify a raw string in C# or escape the \r\n:
var details = DetailExtractor(#"John Doe +22\r\nPong");
or
var details = DetailExtractor("John Doe +22\\r\\nPong");
As everyone else has pointed out there's simpler regexes available to do the same type of matching depending on your needs.
The regex below is slightly simpler, but the string array return is slightly more complex.
public static string[] DetailExtractor1(string input)
{
var match = Regex.Match(input, #"^(?<name>\w+\s+\w+)\s+(?<num>\+\d+)\r\n(?<type>\w+)");
if (match.Success)
{
return new string[] {
match.Groups["name"].Value,
match.Groups["num"].Value,
match.Groups["type"].Value
};
}
return null;
}
You can try with one of these:
[a-z]+ [a-z]+ \+[0-9]{1,}\\r\\n[a-z]+
or:
[a-z\s\\]+\+[0-9]{1,}[a-z\s\\]+
or:
[\w\s]+\+\d{1,}\\r\\n[\w]+
I spend 4 hours on this and still is not clear to me how should this work.
I want use logic from this link. I want to transform
Some123Grouping TO GroupingSome123
I have 3 parts and should change order using replacement ($1, $2, $3)
Also I need something to transform
name#gmail.com TO name
It is not clear to me how to define replacement and what is captured in my case?
Thanks for help, I would relay appreciate it.
$1, $2, etc. are referring to groups (i.e. the indexes of their appearance of declaration). So you need to define groups in your capturing regex. You do this by using parenthesis. For example:
Regex.Replace("Some123Grouping", #"(Some)(123)(Grouping)", #"$3$1$2")
yields "GroupingSome123".
Note that for better readability, groups can also be named and then referenced by their name. For example:
Regex.Replace("mr.smith#gmail.com", #"(?<name>.*)(#gmail.com)", #"${name}")
yields "mr.smith".
BTW, if you are looking for a general (non .NET specific but great) introduction to Regexes, I recommend Regular-Expressions.info.
Simply using your requirement yields
Regex.Replace("name#gmail.com", #"(name)(#gmail.com)", #"$1")
but I suspect what you want is more along the lines of
Regex.Replace("name#gmail.com", #"(\w*)(#.*)", #"$1")
If I understood correctly:
There is pattern with Text followed by Numbers followed by Text if that is correct this should meet your pattern:
string pattern = #"([A-Za-z]+)(\d+)([A-Za-z]+)";
The next step is getting the groups out if it like:
Regex rx = new Regex(pattern);
var match = rx.Match(input);
Then your result may be obtained in 2 ways, the short version:
result = rx.Replace(input, "$3$1$2");
And the long version:
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string input = "Some123Grouping";
string pattern = #"([A-Za-z]+)(\d+)([A-Za-z]+)";
Regex rx = new Regex(pattern);
var match = rx.Match(input);
Console.WriteLine("{0} matches found in:\n {1}",
match.Groups.Count,
input);
var newInput = "";
for(int i= match.Groups.Count;i>0;i--){
newInput += match.Groups[i];
}
Console.WriteLine(newInput);
}
}
Regarding your second issue it seems it is as simple as:
var result ="name#gmail.com".Split('#')[0];
I have a string that I am looking up that can have two possible values:
stuff 1
grouped stuff 1-3
I am not very familiar with using regex, but I know it can be very powerful when used correctly. So forgive me if this question sounds ridiculous in anyway. I was wondering if it would be possible to have some sort of regex code that would only leave the numbers of my string (for example in this case 1 and 1-3) but perhaps if it were the example of 1-3 I could just return the 1 and 3 separately to pass into a function to get the in between.
I hope I am making sense. It is hard to put what I am looking for into words. If anyone needs any further clarification I would be more than happy to answer questions/edit my own question.
To create a list of numbers in string y, use the following:
var listOfNumbers = Regex.Matches(y, #"\d+")
.OfType<Match>()
.Select(m => m.Value)
.ToList();
This is fully possible, but best done with two separate Regexes, say SingleRegex and RangedRegex - then check for one or the other, and pass into a function when the result is RangeRegex.
As long as you're checking for "numbers in a specific place" then extra numbers won't confuse your algorythm. There are also several Regex Testers out there, a simple google Search weill give you an interface to check for various syntax and matches.
Are you just wanting to loop through all of the numbers in the string?
Here's one way you can loop throw each match in a regular expression.
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
Regex r = new Regex(#"\d+");
string s = "grouped stuff 1-3";
Match m = r.Match(s);
while(m.Success)
{
string matchText = m.Groups[0].Value;
Console.WriteLine(matchText);
m = m.NextMatch();
}
}
}
This outputs
1
3
I never use Regular expressions because they seem so complicated though I know that they are dense and powerful. I thought I would give them a shot with your help
How do I use regular expressions to extract all occurences of %sometext% in a string variable and return a string array of matching items?
For example, if the input string is:
set NewVariable=%Variable1%%Variable2%%Variable3%SomeText%Variable4%
The output array would be:
Array[0]=Variable1
Array[1]=Variable2
Array[2]=Variable3
Array[3]=Variable4
The regex should look like this:
%([^%]*)%
The delimiters are on both sides, the capturing group is i between them.
Here is how:
var mc = Regex.Matches(
"quick%brown%%fox%jumps%over%the%lazy%%dog%"
, "%([^%]*)%"
);
foreach (Match m in mc) {
Console.WriteLine(m.Groups[1]);
}
The output of the above looks like this:
brown
fox
over
lazy
dog
Here is a demo on ideone.
var NewVariable = "%Variable1%%Variable2%%Variable3%SomeText%Variable4%";
var Array = Regex.Matches(NewVariable, #"%(.+?)%")
.Cast<Match>()
.Select(m => m.Groups[1].Value)
.ToArray();
Your regular expression is %[^%]+% . Look at the Regex.Matches method.
I have the following string fromat:
session=11;reserID=1000001
How to get string array of number?
My code:
var value = "session=11;reserID=1000001";
var numbers = Regex.Split(value, #"^\d+");
You probably were on the right track but forgot the character class:
Regex.Split(value, #"[^\d]+");
You can also write it shorter by using \D+ which is equivalent.
However, you'd get an empty element at the start of the returned array, so caution when consuming the result. Sadly, Regex.Split() doesn't have an option that removes empty elements (String.Split does, however). A not very pretty way of resolving that:
Regex.Replace(value, #"[^\d;]", "").Split(';');
based on the assumption that the semicolon is actually the relevant piece where you want to split.
Quick PowerShell test:
PS> 'session=11;reserID=1000001' -replace '[^\d;]+' -split ';'
11
1000001
Another option would be to just skip the element:
Regex.Split(...).Skip(1).ToArray();
Regex
.Matches("session=11;reserID=1000001", #"\d+") //match all digit groupings
.Cast<Match>() //promote IEnumerable to IEnumerable<Match> so we can use Linq
.Select(m => m.Value) //for each Match, select its (string) Value
.ToArray() //convert to array, as per question
.Net has built in feature without using RegEx.Try System.Web.HttpUtility.ParseQueryString, passing the string. You would need to reference the System.Web assembly, but it shouldn't require a web context.
var value = "session=11;reserID=1000001";
NameValueCollection numbers =
System.Web.HttpUtility.ParseQueryString(value.Replace(";","&"));
I will re-use my code from another question:
private void button1_Click(object sender, EventArgs e)
{
string sauce = htm.Text; //htm = textbox
Regex myRegex = new Regex(#"[0-9]+(?:\.[0-9]*)?", RegexOptions.Compiled);
foreach (Match iMatch in myRegex.Matches(sauce))
{
txt.AppendText(Environment.NewLine + iMatch.Value);//txt= textbox
}
}
If you want to play around with regex here is a good site: http://gskinner.com/RegExr/
They also have a desktop app: http://gskinner.com/RegExr/desktop/ - It uses adobe air so install that first.
var numbers = Regex.Split(value, #".*?(.\d+).*?");
or
to return each digit:
var numbers = Regex.Split(value, #".*?(\d).*?");