Using Regex, I want to extract digits which are followed by a specific word.
The number of digits is not finite.
Sample input:
My address is 1234#abc.com and you can send SMS to me.
Expected Result.
1234
In this case, the specific word is #abc.com, and the digits followed by this word need to be extracted.
Use the regular expression groups : on MSDN.
In C#, try this :
string pattern = #"(\d+)#abc\.com";
string input = "My address is 15464684#abc.com and you can send SMS to me";
Match match = Regex.Match(input, pattern);
// Get the first named group.
Group group1 = match.Groups[1];
Console.WriteLine("Group 1 value: {0}", group1.Success ? group1.Value : "Empty");
You will need to match 1234#abc.com and use a grouping to extract the digits:
(\d+)\#abc.com
.* (\d+)#abc\.com .* should work.
Related
I'm using Replace(#"[^a-zA-Z]+", "");
leave only letters, but I have a set of numbers or characters that I want to keep as well, ex: 122456 and 112466. But I'm having trouble leaving it only if it's this sequence:
ex input:
abc 1239 asm122456000
I want to:
abscasm122456
tried this: ([^a-zA-Z])+|(?!122456)
My answer doesn't applying Replace(), but achieves a similar result:
(?:[a-zA-Z]+|\d{6})
which captures the group (non-capturing group) with the alphabetic character(s) or a set of digits with 6 occurrences.
Regex 101 & Test Result
Join all the matching values into a single string.
using System.Linq;
Regex regex = new Regex("(?:[a-zA-Z]+|\\d{6})");
string input = "abc 1239 asm12245600";
string output = "";
var matches = regex.Matches(input);
if (matches.Count > 0)
output = String.Join("", matches.Select(x => x.Value));
Sample .NET Fiddle
Alternate way,
using .Split() and .All(),
string input = "abc 1239 asm122456000";
string output = string.Join("", input.Split().Where(x => !x.All(char.IsDigit)));
.NET Fiddle
It is very simple: you need to match and capture what you need to keep, and just match what you need to remove, and then utilize a backreference to the captured group value in the replacement pattern to put it back into the resulting string.
Here is the regex:
(122456|112466)|[^a-zA-Z]
See the regex demo. Details:
(122456|112466) - Capturing group with ID 1: either of the two alternatives
| - or
[^a-zA-Z] - a char other than an ASCII letter (use \P{L} if you need to match any char other than any Unicode letter).
Note the removed + quantifier as [^A-Za-z] also matches digits.
You need to use $1 in the replacement:
var result = Regex.Replace(text, #"(122456|112466)|[^a-zA-Z]", "$1");
I need a regex that can return up to 10 characters in the middle of a file name.
filename: returns:
msl_0123456789_otherstuff.csv -> 0123456789
msl_test.xml -> test
anythingShort.w1 -> anythingSh
I can capture the beginning and end for removal with the following regex:
Regex.Replace(filename, "(^msl_)|([.][[:alnum:]]{1,3}$)", string.Empty); *
but I also need to have only 10 characters when I am done.
Explanation of the regex above:
(^msl_) - match lines that start with "msl_"
| - or
([.] - match a period
[[:alnum]]{1,3} - followed by 1-3 alphanumeric characters
$) - at the end of the line
Note [[:alnum:]] can't work in a .NET regex, because it does not support POSIX character classes. You may use \w (to match letters, digits, underscores) or [^\W_] (to match letters or digits).
You can use your regex and just keep the first 10 chars in the string:
new string(Regex.Replace(s, #"^msl_|\.\w{1,3}$","").Take(10).ToArray())
See the C# demo online:
var strings = new List<string> { "msl_0123456789_otherstuff.csv", "msl_test.xml", "anythingShort.w1" };
foreach (var s in strings)
{
Console.WriteLine("{0} => {1}", s, new string(Regex.Replace(s, #"^msl_|\.\w{1,3}$","").Take(10).ToArray()));
}
Output:
msl_0123456789_otherstuff.csv => 0123456789
msl_test.xml => test
anythingShort.w1 => anythingSh
Using replace with the alternation, removes either of the alternatives from the start and the end of the string, but it will also work when the extension is not present and does not take the number of chars into account in the middle.
If the file extension should be present you might use a capturing group and make msl_ optional at the beginning.
Then match 1-10 times a word character except the _ followed by matching optional word characters until the .
^(?:msl_)?([^\W_]{1,10})\w*\.[^\W_]{2,}$
.NET regex demo (Click on the table tab)
A bit broader match could be using \S instead of \w and match until the last dot:
^(?:msl_)?(\S{1,10})\S*\.[^\W_]{2,}$
See another regex demo | C# demo
string[] strings = {"msl_0123456789_otherstuff.csv", "msl_test.xml","anythingShort.w1", "123456testxxxxxxxx"};
string pattern = #"^(?:msl_)?(\S{1,10})\S*\.[^\W_]{2,}$";
foreach (String s in strings) {
Match match = Regex.Match(s, pattern);
if (match.Success)
{
Console.WriteLine(match.Groups[1]);
}
}
Output
0123456789
test
anythingSh
I'm trying to come up with a regular expression matches the text in bold in all the examples.
Between the string "JZ" and any character before "-"
JZ123456789-301A
JZ134255872-22013
Between the string "JZ" and the last character
JZ123456789D
I have tried the following but it only works for the first example
(?<=JZ).*(?=-)
You can use (?<=JZ)[0-9]+, presuming the desired text will always be numeric.
Try it out here
You may use
JZ([^-]*)(?:-|.$)
and grab Group 1 value. See the regex demo.
Details
JZ - a literal substring
([^-]*) - Capturing group 1: zero or more chars other than -
(?:-|.$) - a non-capturing group matching either - or any char at the end of the string
C# code:
var m = Regex.Match(s, #"JZ([^-]*)(?:-|.$)");
if (m.Success)
{
Console.WriteLine(m.Groups[1].Value);
}
If, for some reason, you need to obtain the required value as a whole match, use lookarounds:
(?<=JZ)[^-]*(?=-|.$)
See this regex variation demo. Use m.Value in the code above to grab the value.
A one-line answer without regex:
string s,r;
// if your string always starts with JZ
s = "JZ123456789-301A";
r = string.Concat(s.Substring(2).TakeWhile(char.IsDigit));
Console.WriteLine(r); // output : 123456789
// if your string starts with anything
s = "A12JZ123456789-301A";
r = string.Concat(s.Substring(s.IndexOf("JZ")).TakeWhile(char.IsDigit));
Console.WriteLine(r); // output : 123456789
Basically, we remove everything before and including the delimiter "JZ", then we take each char while they are digit. The Concat is use to transform the IEnumerable<char> to a string. I think it is easier to read.
Try it online
I want to be able to match the following examples and return array of matches
given text:
some word
another 50.00
some-more 10.10 text
another word
Matches should be (word, followed by space then decimal number (Optionally followed by another word):
another 50.00
some-more 10.10 text
I have the following so far:
string pat = #"\r\n[A-Za-z ]+\d+\.\d{1,2}([A-Za-z])?";
Regex r = new Regex(pat, RegexOptions.IgnoreCase);
Match m = r.Match(input);
but it only matches first item: another 50.00
You do not account for - with [A-Za-z ] and only match some text after a newline.
You can use the following regex:
[\p{L}-]+\p{Zs}*\d*\.?\d{1,2}(?:\p{Zs}*[\p{L}-]+)?
See the regex demo
The [\p{L}-]+ matches 1 or more letters and hyphens, \p{Zs}* matches 0 or more horizontal whitespace symbols, \d*\.?\d{1,2} matches a float number with 1 to 2 digits in the decimal part, and (?:\p{Zs}*[\p{L}-]+)? matches an optional word after the number.
Here is a C# snippet matching all occurrences based on Regex.Matches method:
var res = Regex.Matches(str, #"[\p{L}-]+\p{Zs}*\d*\.?\d{1,2}(?:\p{Zs}*[\p{L}-]+)?")
.Cast<Match>()
.Select(p => p.Value)
.ToList();
Just FYI: if you need to match whole words, you can also use word boundaries \b:
\b[\p{L}-]+\p{Zs}*\d*\.?\d{1,2}(?:\p{Zs}*[\p{L}-]+)?\b
And just another note: if you need to match diacritics, too, you may add \p{M} to the character class containing \p{L}:
[\p{L}\p{M}-]+\p{Zs}*\d*\.?\d{1,2}(?:\p{Zs}*[\p{L}\p{M}-]+)?\b
I have the following string:
#delimabc#delim#delim123#delim#delim456#delim
and I need to write a .Net RegEx that finds 3 matches in this example (but assume the number of matches will be variable:
abc
123
456
How can I write a RegEx so that the expression only matches the first and second #delim, and then the third and fourth and so on?
The following will of course capture from the first to the last instance of the #delim string.
#delim(.+)+#delim
You could use look behind like:
(?<=#delim)\w+
(?<=#delim) is using a Positive Lookbehind which will match the characters #delim literally (case sensitive)
while \w+ will match any word character from [a-zA-Z0-9_]. To include or exclude characters you could replace \w by [a-zA-Z0-9_] and include the new characters or remove those that should not be evaluated in your expression.
Online Demo
Here is .NET Online Demo:
.NET Online Demo
VB.NET version
Dim sampleInput="#delimabc#delim#delim123#delim#delim456#delim"
Dim results = Regex.Matches(sampleInput,"(?<=#delim)\w+")
For Each item As Group In results
Console.WriteLine("Line: {0}", item)
Next
C# Version
var sampleInput = "#delimabc#delim#delim123#delim#delim456#delim";
var results = Regex.Matches(sampleInput, "(?<=#delim)\\w+");
foreach (Group item in results) {
Console.WriteLine("Line: {0}", item);
}
Updated version:
(?<=#delim)[^#].+?(?=#delim|$)
#delim(.+?)#delim
Try this .Set g flag.Just modifed your regex to add ?.Grab the caotures.See demo.
http://regex101.com/r/uH3tP3/1
You can use split on this regex:
(?:#delim)+
RegEx Demo
Alternatively replace given regex pattern by an empty string.