I'm looking for a regex in C#.net to extract printers from a list in a script.
This is an example:
#set nr=2
#if not exist "%userprofile%\Version%nr%.txt" goto reload
#goto koppla
:reload
#echo skrivare>"%userprofile%\Version%nr%.txt"
#del "%userprofile%\zxy-*.txt"
#call skrivare.cmd
#exit
:koppla
#%connect1% \\%Print2%\Lund-M1
#%connect2% \\%Print2%\MAR-M1
#%connect2% \\%Print2%\MAR-M2
I would like to get the names (Lund-M1, MAR-M1, MAR-M2) of the printers in a array to foreach.
I really appreciate any help on this, my mind doesn't work with Regex.
Thank you in advance!
You could do something quite simple, like searching for the Print2 prefix:
\\\\%Print2%\\(.*)
This gives the following output on http://www.regexer.com. You'd then need to access the first group of each Match object to grab the part of the string you are after.
Edit
If you want to encapsulate different print numbers use the following which allows the 2 to be exchanged with any other number.
\\\\%Print[0-9]%\\(.*)
(?m:(?<=^#\%connect\d\% \\\\(.*?\\)*)[^\\]+$)
will give three matches over your script, with values
Lund-M1
MAR-M1
MAR-M2
So
Regex.Matches(input, #"(?m:(?<=^#\%connect\d\% \\\\(.*?\\)*)[^\\]+$)")
.Cast<Match>()
.Select(m => m.Value)
.ToArray()
gives you what you need.
This checks for line starting #%connect then any digit followed by % then pulls the last segment of any path of the form \\something\something\something\AnyNonBackslashChars
foreach (Match match in Regex.Matches(text,
#"^#%connect\d+%\s+\\\\%Print2%\\(.*?)\s*$", RegexOptions.IgnoreCase | RegexOptions.Multiline))
{
if (match.Success)
{
var name = match.Groups[1];
}
}
Related
I'm trying to extract values from a string which are between << and >>. But they could happen multiple times.
Can anyone help with the regular expression to match these;
this is a test for <<bob>> who like <<books>>
test 2 <<frank>> likes nothing
test 3 <<what>> <<on>> <<earth>> <<this>> <<is>> <<too>> <<much>>.
I then want to foreach the GroupCollection to get all the values.
Any help greatly received.
Thanks.
Use a positive look ahead and look behind assertion to match the angle brackets, use .*? to match the shortest possible sequence of characters between those brackets. Find all values by iterating the MatchCollection returned by the Matches() method.
Regex regex = new Regex("(?<=<<).*?(?=>>)");
foreach (Match match in regex.Matches(
"this is a test for <<bob>> who like <<books>>"))
{
Console.WriteLine(match.Value);
}
LiveDemo in DotNetFiddle
While Peter's answer is a good example of using lookarounds for left and right hand context checking, I'd like to also add a LINQ (lambda) way to access matches/groups and show the use of simple numeric capturing groups that come handy when you want to extract only a part of the pattern:
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
// ...
var results = Regex.Matches(s, #"<<(.*?)>>", RegexOptions.Singleline)
.Cast<Match>()
.Select(x => x.Groups[1].Value);
Same approach with Peter's compiled regex where the whole match value is accessed via Match.Value:
var results = regex.Matches(s).Cast<Match>().Select(x => x.Value);
Note:
<<(.*?)>> is a regex matching <<, then capturing any 0 or more chars as few as possible (due to the non-greedy *? quantifier) into Group 1 and then matching >>
RegexOptions.Singleline makes . match newline (LF) chars, too (it does not match them by default)
Cast<Match>() casts the match collection to a IEnumerable<Match> that you may further access using a lambda
Select(x => x.Groups[1].Value) only returns the Group 1 value from the current x match object
Note you may further create a list of array of obtained values by adding .ToList() or .ToArray() after Select.
In the demo C# code, string.Join(", ", results) generates a comma-separated string of the Group 1 values:
var strs = new List<string> { "this is a test for <<bob>> who like <<books>>",
"test 2 <<frank>> likes nothing",
"test 3 <<what>> <<on>> <<earth>> <<this>> <<is>> <<too>> <<much>>." };
foreach (var s in strs)
{
var results = Regex.Matches(s, #"<<(.*?)>>", RegexOptions.Singleline)
.Cast<Match>()
.Select(x => x.Groups[1].Value);
Console.WriteLine(string.Join(", ", results));
}
Output:
bob, books
frank
what, on, earth, this, is, too, much
You can try one of these:
(?<=<<)[^>]+(?=>>)
(?<=<<)\w+(?=>>)
However you will have to iterate the returned MatchCollection.
Something like this:
(<<(?<element>[^>]*)>>)*
This program might be useful:
http://sourceforge.net/projects/regulator/
I have a string s which reads my batch file content.
Suppose the content of s is as follows:
"\t\r\n##echo off\r\necho \"Hello World!!!\"\r\necho \"One\"\r\nset /p DUMMY=Hit ENTER to continue...\r\ncall second.bat\r\necho \"done!!!\"\r\ncall third.bat\r\necho \"done 3!!!\""
i want to write a condition which does the below,
while (s.Contains("call")) && (if string next to "call" contains(.bat))
how to acheive this?
I am new to c#. Please help me in this regard.
thanks in advance
You can split the string on new lines and process only the lines you want as follows:
foreach (string line in s.Split("\r\n", StringSplitOptions.None).Where(x => x.ToLower().StartsWith("call") && x.ToLower().EndsWith(".bat")))
{
// do stuff here
}
It seems that you are parsing some kind of log; in this case I suggest using regular expressions, e.g.
using System.Text.RegularExpressions;
...
string source =
"\t\r\n##echo off\r\necho \"Hello World!!!\"\r\necho \"One\"\r\nset /p DUMMY=Hit ENTER to continue...\r\ncall second.bat\r\necho \"done!!!\"\r\ncall third.bat\r\necho \"done 3!!!\"";
var matches = Regex
.Matches(source, #"call.+?\.bat", RegexOptions.IgnoreCase)
.OfType<Match>()
.Select(match => match.Value);
// call second.bat
// call third.bat
foreach (string match in matches) {
...
}
It's unclear what is "string next", in the code above I've treated it as "after". In case it means "after several white spaces" the pattern will be
.Matches(source, #"call\s+?\.bat", RegexOptions.IgnoreCase)
The first thing that comes to my mind is using the text.Split ('\n', '\r') method. This way you get an array of strings which are separated by those line break symbols. Because you'd get empty strings, you should also filter those out. For that, I would recommend converting the array to a list, iterate through all elements and remove all empty strings (consider using string.IsNullOrEmpty (text)).
If you always have \r\n, you can use text.Split("\r\n", StringSplitOptions.None) instead, and don't have to worry about empty strings in between. You could still convert it to a list for easier use.
Then you would get a fine list of the entire content separated through line breaks. Now you could loop through that and do whatever you want.
Lets say I have a text file with the line below within it. I want to take both values within the quotations by matching between (" and "), so that would be I retreive ABC and DEF and put them in a string list or something, what's the best way of doing this? It's so annoying
If EXAMPLEA("ABC") AND EXAMPLEB("DEF")
Assuming a case where the value between the double quotes can not contain escaped double quotes might work like this:
var text = "If EXAMPLEA(\"ABC\") AND EXAMPLEB(\"DEF\")";
Regex pattern = new Regex("\"[^\"]*\"");
foreach (Match match in pattern.Matches(text))
{
Console.WriteLine(match.Value.Trim('"'));
}
But this is only one of the many ways you could do it and maybe not the smartest way out there. Try something yourself!
Best way...
List<string> matches=Regex.Matches(File.ReadAllText(yourPath),"(?<="")[^""]*(?="")")
.Cast<Match>()
.Select(x=>x.Value)
.ToList();
This pattern should do the trick:
\"([^"]*)\"
string str = "If EXAMPLEA(\"ABC\") AND EXAMPLEB(\"DEF\")";
MatchCollection matched = Regex.Matches(str, #"\""([^\""]*)\""");
foreach (Match match in matched)
{
Console.WriteLine(match.Groups[1].Value);
}
Note that the quotation marks are doubled in the actual code in order to escape them. And the code refers to group [1] to get just the part inside the parentheses.
IEnumerable<string> matches =
from Match match
in Regex.Matches(File.ReadAllText(filepath), #"\""([^\""]*)\""")
select match.Groups[1].Value;
Others already posted some answers, but my takes into account that you just want ABC and DEF in your example, without quotation marks and save it in a IEnumerable<string>.
i'v got code
s = Regex.Match(item.Value, #"\/>.*?\*>", RegexOptions.IgnoreCase).Value;
it returns string like '/>test*>', i can replace symbols '/>' and '*>', but how can i return string without this symbols , only string 'test' between them?
You can save parts of the regex by putting ()'s around the area. so for your example:
// item.Value == "/>test*>"
Match m = Regex.Match(item.Value, #"\/>(.*?)\*>");
Console.WriteLine(m.Groups[0].Value); // prints the entire match, "/>test*>"
Console.WriteLine(m.Groups[1].Value); // prints the first saved group, "test*"
I also removed RegexOptions.IgnoreCase because we aren't dealing with any letters specifically, whats an uppercase /> look like? :)
You can group patterns inside the regx and get those from the match
var match= Regex.Match(item.Value, #"\/>(?<groupName>.*)?\*>", RegexOptions.IgnoreCase);
var data= match.Groups["groupName"].Value
You can also use look-ahead and look-behind. For your example it would be:
var value = Regex.Match(#"(?<=\/>).*?(?=\*>)").Value;
I need to create a regex that can match multiple strings. For example, I want to find all the instances of "good" or "great". I found some examples, but what I came up with doesn't seem to work:
\b(good|great)\w*\b
Can anyone point me in the right direction?
Edit: I should note that I don't want to just match whole words. For example, I may want to match "ood" or "reat" as well (parts of the words).
Edit 2: Here is some sample text: "This is a really great story."
I might want to match "this" or "really", or I might want to match "eall" or "reat".
If you can guarantee that there are no reserved regex characters in your word list (or if you escape them), you could just use this code to make a big word list into #"(a|big|word|list)". There's nothing wrong with the | operator as you're using it, as long as those () surround it. It sounds like the \w* and the \b patterns are what are interfering with your matches.
String[] pattern_list = whatever;
String regex = String.Format("({0})", String.Join("|", pattern_list));
(good)*(great)*
after your edit:
\b(g*o*o*d*)*(g*r*e*a*t*)*\b
I think you are asking for smth you dont really mean
if you want to search for any Part of the word, you litterally searching letters
e.g. Search {Jack, Jim} in "John and Shelly are cool"
is searching all letters in the names {J,a,c,k,i,m}
*J*ohn *a*nd Shelly *a*re
and for that you don't need REG-EX :)
in my opinion,
A Suffix Tree can help you with that
http://en.wikipedia.org/wiki/Suffix_tree#Functionality
enjoy.
I don't understand the problem correctly:
If you want to match "great" or "reat" you can express this by a pattern like:
"g?reat"
This simply says that the "reat"-part must exist and the "g" is optional.
This would match "reat" and "great" but not "eat", because the first "r" in "reat" is required.
If you have the too words "great" and "good" and you want to match them both with an optional "g" you can write this like this:
(g?reat|g?ood)
And if you want to include a word-boundary like:
\b(g?reat|g?ood)
You should be aware that this would not match anything like "breat" because you have the "reat" but the "r" is not at the word boundary because of the "b".
So if you want to match whole words that contain a substring link "reat" or "ood" then you should try:
"\b\w*?(reat|ood)\w+\b"
This reads:
1. Beginning with a word boundary begin matching any number word-characters, but don't be gready.
2. Match "reat" or "ood" enshures that only those words are matched that contain one of them.
3. Match any number of word characters following "reat" or "ood" until the next word boundary is reached.
This will match:
"goodness", "good", "ood" (if a complete word)
It can be read as: Give me all complete words that contain "ood" or "reat".
Is that what you are looking for?
I'm not entirely sure that regex alone offers a solution for what you're trying to do. You could, however, use the following code to create a regex expression for a given word. Although, the resulting regex pattern has the potential to become very long and slow:
function wordPermutations( $word, $minLength = 2 )
{
$perms = array( );
for ($start = 0; $start < strlen( $word ); $start++)
{
for ($end = strlen( $word ); $end > $start; $end--)
{
$perm = substr( $word, $start, ($end - $start));
if (strlen( $perm ) >= $minLength)
{
$perms[] = $perm;
}
}
}
return $perms;
}
Test Code:
$perms = wordPermutations( 'great', 3 ); // get all permutations of "great" that are 3 or more chars in length
var_dump( $perms );
echo ( '/\b('.implode( '|', $perms ).')\b/' );
Example Output:
array
0 => string 'great' (length=5)
1 => string 'grea' (length=4)
2 => string 'gre' (length=3)
3 => string 'reat' (length=4)
4 => string 'rea' (length=3)
5 => string 'eat' (length=3)
/\b(great|grea|gre|reat|rea|eat)\b/
Just check for the boolean that Regex.IsMatch() returns.
if (Regex.IsMatch(line, "condition") && Regex.IsMatch(line, "conditition2"))
The line will have both regex, right.