RegEx Expression for Parenthesis Matching - c#

I need some help coming up with a C# regular expression that can take a string like:
string input = "Test1='1' OR (Test2 = '2' OR (Test3 = '3')) OR (Test4 = '4')";
and return match items like:
1 => Test1='1' OR
2 => (Test2 = '2' OR (Test3 = '3'))
3 => OR
4 => (Test4 = '4')

Look into Grouping Constructs in Regular Expressions
To get you started.. here's a sample for the input you provided.
string pattern = #"(Test1='1' OR) \(Test2 = '2'";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
foreach(Group group in match.Groups)
{
Console.WriteLine(group);
}
}
Console.ReadKey();

Related

I want to convert all number between tag with regex in a file txt

I'm trying to write a regex to modify numbers to two decimals.
For each number between the <td> tags, I want to modify so it includes two decimals.
Input
<TD>25.5</TD>
<TD>45.6</TD>
<TD>19</TD>
<TD>25</TD>
Desired output
<TD>25.50</TD>
<TD>45.60</TD>
<TD>19.00</TD>
<TD>25.00</TD>
Code:
string text = File.ReadAllText("pop.txt");
try
{
string pattern = #"(<TD>(.+?)</TD>)";
var matches = Regex.Matches(text, pattern);
var result = (from Match m in matches select (m.Groups[2].ToString())).ToList<string>();
foreach (var item in result)
{
var a = Convert.ToDouble(item).ToString("#,##.00");
string s = String.Format("{0:0.##}", item);
text = text.Replace(item,a);
}
}
catch (Exception ex)
{
}
Answer
var input = "<TD>25.5</TD><TD>45.6</TD><TD>19</TD><TD>25</TD><TD>.03</TD>";
var regex = new Regex(#"<TD>(\d*?)\.?(\d?\d?).*?</TD>");
var output = regex.Replace(input, match => {
var rigth = match.Groups[1].Value;
var left = match.Groups[2].Value.PadRight(2, '0');
return $"<TD>{(rigth.Length == 0 ? "0" : rigth)}.{left}</TD>";
});
Explanation
<TD> find <TD>
(\d*?) find 0 or more digits and capture them (?not greedy)
\.? optional dot
(\d?\d?) 2 optional digits captured
.*? rest untill </TD>

How to find 1 in my string but ignore -1 C#

I have a string
string test1 = "255\r\n\r\n0\r\n\r\n-1\r\n\r\n255\r\n\r\n1\r";
I want to find all the 1's in my string but not the -1's. So in my string there is only one 1. I use string.Contain("1") but this will find two 1's. So how do i do this?
You can use regular expression:
string test1 = "255\r\n\r\n0\r\n\r\n-1\r\n\r\n255\r\n\r\n1\r";
// if at least one "1", but not "-1"
if (Regex.IsMatch(test1, "(?<!-)1")) {
...
}
the pattern is exactly 1 which is not preceed by -. To find all the 1s:
var matches = Regex
.Matches(test1, "(?<!-)1")
.OfType<Match>()
.ToArray(); // if you want an array
Try this simple solution:
Note : You can convert this to extension Method Easily.
static List<int> FindIndexSpecial(string search, char find, char ignoreIfPreceededBy)
{
// Map each Character with its Index in the String
var characterIndexMapping = search.Select((x, y) => new { character = x, index = y }).ToList();
// Check the Indexes of the excluded Character
var excludeIndexes = characterIndexMapping.Where(x => x.character == ignoreIfPreceededBy).Select(x => x.index).ToList();
// Return only Indexes who match the 'find' and are not preceeded by the excluded character
return (from t in characterIndexMapping
where t.character == find && !excludeIndexes.Contains(t.index - 1)
select t.index).ToList();
}
Usage :
static void Main(string[] args)
{
string test1 = "255\r\n\r\n0\r\n\r\n-1\r\n\r\n255\r\n\r\n1\r";
var matches = FindIndexSpecial(test1, '1', '-');
foreach (int index in matches)
{
Console.WriteLine(index);
}
Console.ReadKey();
}
You could use String.Split and Enumerable.Contains or Enumerable.Where:
string[] lines = test1.Split(new[] {Environment.NewLine, "\r"}, StringSplitOptions.RemoveEmptyEntries);
bool contains1 = lines.Contains("1");
string[] allOnes = lines.Where(l => l == "1").ToArray();
String.Contains searches for sub-strings in a given string instance. Enumerable.Contains looks if there's at least one string in the string[] which equals it.

Regular expression or function to search for word and return the next one

I'm looking for a function/regular expression that finds the given word and retruns the next one for example:
Giving the input "is"
and searching in this string
"the force is strong with you but you are not a jedi yet"
would return "strong"
Searching for "you" would return an array containing {"but","are"}.
Im'm looking for a code sample preferably in PHP or C#.
You could try
(?:\bis\b)\s*(\b\w*\b)
Example
PHP Code Example:
<?php
$sourcestring="your source string";
preg_match_all('/(?:\bis\b)\s*(\b\w*\b)/i',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>
$matches Array:
(
[0] => Array
(
[0] => Is that
[1] => is strong
[2] => is that
)
[1] => Array
(
[0] => that
[1] => strong
[2] => that
)
)
Using C#:
var search = "you";
var str = "the force is strong with you but you are not a jedi yet";
var matches = Regex.Matches(str, search + #"\s(\w+)");
foreach (Match word in matches)
{
Console.WriteLine(word.Groups[1].Value);
}
This assumes that there is a single space after the word you search for. The same regular expression would work in PHP (obviously without the # and with delimiters).
C# sample:
var words = new List<string>();
string wordToSearch = "you";
string strTargetString = #"the force is strong with you but you are not a jedi youu yet";
string strRegex = string.Format(#"(\b{0}\b)\s+(\b.+?\b)", wordToSearch);
RegexOptions myRegexOptions = RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.CultureInvariant;
Regex myRegex = new Regex(strRegex, myRegexOptions);
foreach(Match myMatch in myRegex.Matches(strTargetString))
{
string word = myMatch.Groups[2].Value;
words.Add(word);
}
A php function without regex :
$str = "the force is strong with you but you are not a jedi yet";
$res = getTheNextOne('you', $str);
echo '<pre>' . print_r($res,true) . '</pre>';
//Array
//(
// [0] => but
// [1] => are
//)
function getTheNextOne($needle, $str) {
$res = array();
$tmp = explode(' ', $str);
$length = count($tmp);
//$length-1 as there is no next word for the last one
for($i=0; $i < $length-1; $i++) {
if($tmp[$i] == $needle) {
$res[] = $tmp[$i+1];
}
}
$nbFound = count($res);
if($nbFound == 0) {
return null;
} elseif ($nbFound == 1) {
return $res[0];
} else {
return $res;
}
}

How to find out if regexp parsed string part contains another string?

Say we have a list of strings L, a given string S. We have a regexp like (\w+)\-(\w+) we want to get all L elements for which S matches $1 of regexp. How to do such thing?
You can do this:
// sample data
string[] L = new string[] { "bar foo", "foo bar-zoo", "bar-", "zoo bar-foo" };
string S = "bar";
Regex regex = new Regex(#"(\w+)\-(\w+)");
string[] res = L.Where(l => {
Match m = regex.Match(l);
if (m.Success) return m.Groups[1].Value == S;
else return false;
}).ToArray();
and get
foo bar-zoo
zoo bar-foo
An easier way that probably works out for you too is to include S in the regex:
Regex regex = new Regex(S + #"\-(\w+)");
string[] res = L.Where(l => regex.Match(l).Success).ToArray();

C# - Sorting Data to/from ListBoxes with Regex

I have a file with data in it that I would like to split up into three different ListBoxes. I want the first ListBox to contain all of the data (a new list item for every line of data read from the text document).
Main ListBox:
D1
D2
C9
R7
R1
C130
D99
Q9
Second ListBox: (after a regex was used to match values that start with D)
D1
D2
D99
Third ListBox: (after a regex was used to match values that start with C)
C9
C130
And after those values were matched for the SECOND and THIRD ListBoxes, the
New Main ListBox will look like this:
R7
R1
Q9
CODE
static List<string> findPackagePlacementOneType(List<string> list)
{
// Creates a new list to return with new format.
var result = new List<string>();
// Checks each line in the list.
foreach (var line in list)
{
// PLACEMENT ONE Regex
Match regexRES = Regex.Match(line, #"^.+(RES)");
Match regex0402 = Regex.Match(line, #"^.+(0402)");
Match regex0201 = Regex.Match(line, #"^.+(0201)");
Match regex0603 = Regex.Match(line, #"^.+(0603)");
Match regex0805 = Regex.Match(line, #"^.+(0805)");
Match regex1206 = Regex.Match(line, #"^.+(1206)");
Match regex1306 = Regex.Match(line, #"^.+(1306)");
Match regex1608 = Regex.Match(line, #"^.+(1608)");
Match regex3216 = Regex.Match(line, #"^.+(3216)");
Match regex2551 = Regex.Match(line, #"^.+(2551)");
Match regex1913 = Regex.Match(line, #"^.+(1913)");
Match regex1313 = Regex.Match(line, #"^.+(1313)");
Match regex2513 = Regex.Match(line, #"^.+(2513)");
Match regex5125 = Regex.Match(line, #"^.+(5125)");
Match regex2525 = Regex.Match(line, #"^.+(2525)");
Match regex5619 = Regex.Match(line, #"^.+(5619)");
Match regex3813 = Regex.Match(line, #"^.+(3813)");
Match regex1508 = Regex.Match(line, #"^.+(1508)");
Match regex6431 = Regex.Match(line, #"^.+(6431)");
Match regex2512 = Regex.Match(line, #"^.+(2512)");
Match regex1505 = Regex.Match(line, #"^.+(1505)");
Match regex2208 = Regex.Match(line, #"^.+(2208)");
Match regex1005 = Regex.Match(line, #"^.+(1005)");
Match regex1010 = Regex.Match(line, #"^.+(1010)");
Match regex2010 = Regex.Match(line, #"^.+(2010)");
Match regex0505 = Regex.Match(line, #"^.+(0505)");
Match regex0705 = Regex.Match(line, #"^.+(0705)");
Match regex1020 = Regex.Match(line, #"^.+(1020)");
Match regex1812 = Regex.Match(line, #"^.+(1812)");
Match regex2225 = Regex.Match(line, #"^.+(2225)");
Match regex5764 = Regex.Match(line, #"^.+(5764)");
Match regex4532 = Regex.Match(line, #"^.+(4532)");
Match regex1210 = Regex.Match(line, #"^.+(1210)");
Match regex0816 = Regex.Match(line, #"^.+(0816)");
Match regex0363 = Regex.Match(line, #"^.+(0363)");
Match regexSOT = Regex.Match(line, #"^.+(SOT)");
if (regexRES.Success || regex0402.Success || regex0201.Success || regex0603.Success ||
regex0805.Success || regex1206.Success || regex1306.Success || regex1608.Success ||
regex3216.Success || regex2551.Success || regex1913.Success || regex1313.Success ||
regex2513.Success || regex5125.Success || regex2525.Success || regex5619.Success ||
regex3813.Success || regex1508.Success || regex6431.Success || regex2512.Success ||
regex1505.Success || regex2208.Success || regex1005.Success || regex1010.Success ||
regex2010.Success || regex0505.Success || regex0705.Success || regex1020.Success ||
regex1812.Success || regex2225.Success || regex5764.Success || regex4532.Success ||
regex1210.Success || regex0816.Success || regex0363.Success || regexSOT.Success)
{
result.Add(string.Join(" ", line));
}
else
result.Remove(line);
}
// Returns the new list so it can be formatted further.
return result;
}
// Finds the placement 2 package types.
static List<string> findPackagePlacementTwoType(List<string> list)
{
// Creates a new list to return with new format.
var result = new List<string>();
// Checks each line in the list.
foreach (var line in list)
{
// PLACEMENT TWO Regex
Match regexBGA = Regex.Match(line, #"^.+(BGA)");
Match regexSOP8 = Regex.Match(line, #"^.+(SOP8)");
Match regexQSOP = Regex.Match(line, #"^.+(QSOP)");
Match regexTQSOP = Regex.Match(line, #"^.+(TQSOP)");
Match regexSOIC16 = Regex.Match(line, #"^.+(SOIC16)");
Match regexSOIC12Plus = Regex.Match(line, #"^.+(SOIC12)");
Match regexSOIC8 = Regex.Match(line, #"^.+(SOIC8)");
Match regexSO8 = Regex.Match(line, #"^.+(SO8)");
Match regexSO08 = Regex.Match(line, #"^.+(SO08)");
Match regexCQFP = Regex.Match(line, #"^.+(CQFP)");
Match regexLCC = Regex.Match(line, #"^.+(LCC)");
Match regexLGA = Regex.Match(line, #"^.+(LGA)");
Match regexOSCCC = Regex.Match(line, #"^.+(OSCCC)");
Match regexPLCC = Regex.Match(line, #"^.+(PLCC)");
Match regexQFN = Regex.Match(line, #"^.+(QFN)");
Match regexQFP = Regex.Match(line, #"^.+(QFP)");
Match regexSOJ = Regex.Match(line, #"^.+(SOJ)");
Match regexSON = Regex.Match(line, #"^.+(SON)");
if (regexBGA.Success || regexSOP8.Success || regexQSOP.Success || regexTQSOP.Success ||
regexSOIC16.Success || regexSOIC12Plus.Success || regexSOIC8.Success || regexSO8.Success ||
regexSO08.Success || regexCQFP.Success || regexLCC.Success || regexLGA.Success ||
regexOSCCC.Success || regexPLCC.Success || regexQFN.Success || regexQFP.Success ||
regexSOJ.Success || regexSON.Success)
{
result.Add(string.Join(" ", line));
}
else
result.Remove(line);
}
// Returns the new list so it can be formatted further.
return result;
}
static List<string> findPackagePlacementChoiceType(List<string> list)
{
// Creates a new list to return with new format.
var result = new List<string>();
// Checks each line in the list.
foreach (var line in list)
{
// PLACEMENT CHOICE Regex
Match regexCAP = Regex.Match(line, #"^.+(CAP)");
Match regexIND = Regex.Match(line, #"^.+(IND)");
Match regexMELF = Regex.Match(line, #"^.+(MELF)");
Match regexDIOM = Regex.Match(line, #"^.+(DIOM)");
Match regexSOD = Regex.Match(line, #"^.+(SOD)");
Match regexSTO = Regex.Match(line, #"^.+(STO)");
Match regexTO = Regex.Match(line, #"^.+(TO)");
if (regexCAP.Success || regexIND.Success || regexMELF.Success || regexDIOM.Success ||
regexSOD.Success || regexSTO.Success || regexTO.Success)
{
result.Add(string.Join(" ", line));
}
else
result.Remove(line);
}
// Returns the new list so it can be formatted further.
return result;
}
QUESTIONS
I currently have my regular expressions that sort through and divide the file up into three seperate ListBoxes.. However... I would rather have the data placed in one of the ListBoxes and then sorted/removed from that ListBox if it matches the proper regular expression.
How do I go about loading the .txt document into the ListBox (with every new line being a new item in the ListBox) and then going through each line in the main ListBox with regex to determine if the lines go into a different second or third ListBox or stay in the main ListBox?
Instead of multiple regexes you could just combine them into one.
You also don’t need to call Regex.Match followed by match.Success; just call Regex.IsMatch.
I don’t understand why you are using result.Remove(line). You never added that non-matching line, so why do you need to remove it?
Finally, I don’t think you need to make the method specific to using List<string>. You can make it more general by specifying IEnumerable<string>.
I’ve rewritten the first one to demonstrate the principle:
static IEnumerable<string> findPackagePlacementOneType(IEnumerable<string> list)
{
return list.Where(line => Regex.IsMatch(line,
#"^.+(RES|0402|0201|0603|0805|1206|1306|1608|3216|2551|1913|1313|2513" +
#"|5125|2525|5619|3813|1508|6431|2512|1505|2208|1005|1010|2010|0505" +
#"|0705|1020|1812|2225|5764|4532|1210|0816|0363|SOT)"
));
}
If you ever really need a new List<string>, you can just add .ToList() after a call to findPackagePlacementOneType.
I'd recommend making a few ObservableCollection<string>s, one for each of your ListBoxes. ObservableCollections raise events when items are added or removed, which allows things like ListBoxes to automatically update when they change. Say they're called items1, 2, and 3. Start with items1 = new ObservableCollection<string>(list);, and the other initialized as empty collections. Also, rework the methods you posted to take a single string and return a bool saying whether it matched any.
Part 1, putting your collections of strings into the ListBoxes:
mainListBox.ItemsSource = items1;
listBox2.ItemsSource = items2;
listBox3.ItemsSource = items3;
Part 2, going through each item in the list:
foreach (string str in items1.ToArray())
{
if (isPackagePlacementOneType(str))
{
items1.Remove(str);
items2.Add(str);
} else if ...
}
The .ToArray() is the LINQ extension; it's needed because you can't modify an enumerable that you're iterating through.
Part 3: Also, I'd recommend reworking the methods a bit, based on the Do not Repeat Yourself (DRY) principle:
static readonly string[] match1 = new [] { "RES", ... };
static readonly string[] match2 = new [] { "BGA", ... };
static readonly string[] match3 = new [] { "CAP", ... };
//(then in the methods)
return match1.Any(x=>Regex.Match(line, #"^.+(" + x + ")").Success);
This also has the benefit of not needing to evaluate dozens of regex's that don't end up being read at all.

Categories

Resources