How to match number and minus operator with regex? - c#

In fact, i'd like to match the things before and after the " ??"
my code is below:
//enter code here
Regex r = new Regex(#"(?'value'[0-9\-\./TSE]{1,}) \?\?(?'index'[A-Za-z:]{1,}");
string s=
#"39 ??Issue:
9 ??Pages:
1307-1325 ??DOI:
10.1109/TSE.2013.14 ??Published:";
As you can see, i'd like to match these things:
value="39" index = "Issue:"
value="9" index = "Pages:"
value="1307-1325" index = "DOI:"
value="10.1109/TSE.2013.14" index = "Published:"
I think just change one or two characters in the regex can solve this problem. anyone can help?

If you simply want the information before and after the ??, and it will always be in that format (value ?? index), then Regex is way overkill for this. Simply use String.Split:
string s= #"39 ??Issue:
9 ??Pages:
1307-1325 ??DOI:
10.1109/TSE.2013.14 ??Published:";
string[] splitValues = s.Split(new string[] { "??", "\r\n" }, StringSplitOptions.None);
for (int i = 0; i < splitValues.Length; i += 2)
{
Console.WriteLine("value={0} index={1}", splitValues[i].Trim(), splitValues[i + 1].Trim());
}
This will split on the ?? and the newline, resulting in the output you're looking for:
value="39" index = "Issue:"
value="9" index = "Pages:"
value="1307-1325" index = "DOI:"
value="10.1109/TSE.2013.14" index = "Published:"
The coded above splits the string on ?? and \r\n (end of line/newline), resulting in an array of elements, with the first element being the first value, the second element being the second value, the third element being the first value of the second line, the fourth element being the second value of the second line, etc.
The for loop is pretty straight forward - the i += 2 part simply increments the loop counter by 2 (instead of the usual 1 [i++]), so it prints the value and index of each line in the input.

Related

Detecting newline in string and adding a character before it

Hi I have the folowing string:
* lalalalalaal
* 12121212121212
* 36363636363636
* 21454545454545454
every line of the list start with - "\r\n* "
is there a way to detect the "\r\n* " symbol at the beginning and maybe replace it with numbers 1, 2, 3, ...n. So in example something like this:
1. lalalalalaal
2. 12121212121212
3. 36363636363636
4. 21454545454545454
I imagine building an array and running the for loop would be required but i do not get my head around where I am supposed to start.
If I understand you correctly, you have a string that looks like this:
"\r\n* lalalalalaal\r\n* 12121212121212\r\n* 36363636363636\r\n* 21454545454545454"
And you want to replace "\r\n*" with "\r\n1.", where the number 1 increments each time the search string is found.
If so, here's one way to do it: Use the IndexOf method to find the location of the string you're searching for, keep a counter variable that increments every time you find the search term, and then use Substring to get the sub strings before and after the part to replace ('*'), and then put the counter's value between them:
static string ReplaceWithIncrementingNumber(string input, string find, string partToReplace)
{
if (input == null || find == null ||
partToReplace == null || !find.Contains(partToReplace))
{
return input;
}
// Get the index of the first occurrence of our 'find' string
var index = input.IndexOf(find);
// Track the number of occurrences we've found, to use as a replacement string
var counter = 1;
while (index > -1)
{
// Get the leading string up to '*', add the counter, then add the trailing string
input = input.Substring(0, index) +
find.Replace(partToReplace, $"{counter++}.") +
input.Substring(index + find.Length);
// Find the next occurrence of our 'find' string
index = input.IndexOf(find, index + find.Length);
}
return input;
}
Here's a sample using your input string:
static void Main()
{
var input = "\r\n* lalalalalaal\r\n* 12121212121212\r\n* " +
"36363636363636\r\n* 21454545454545454";
Console.WriteLine(ReplaceWithIncrementingNumber(input, "\r\n*", "*"));
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
You can use Linq and String.Replace to achieve it.(Believe you already have your strings as List as mentioned in second part of your OP)
var result = list.Select((x,index)=> $"{index+1}.{x.Replace("\r\n* ",string.Empty)}");
In case, you do not have it as list, then you can split your string as
var result = str.Split(new string[]{Environment.NewLine},StringSplitOptions.RemoveEmptyEntries)
.Select((x,index)=> $"{index+1}.{x.Replace("* ",string.Empty)}");

How to extract string at a certain character that is repeated within string?

How can I get "MyLibrary.Resources.Images.Properties" and "Condo.gif" from a "MyLibrary.Resources.Images.Properties.Condo.gif" string.
I also need it to be able to handle something like "MyLibrary.Resources.Images.Properties.legend.House.gif" and return "House.gif" and "MyLibrary.Resources.Images.Properties.legend".
IndexOf LastIndexOf wouldn't work because I need the second to last '.' character.
Thanks in advance!
UPDATE
Thanks for the answers so far but I really need it to be able to handle different namespaces. So really what I'm asking is how to I split on the second to last character in a string?
You can use LINQ to do something like this:
string target = "MyLibrary.Resources.Images.Properties.legend.House.gif";
var elements = target.Split('.');
const int NumberOfFileNameElements = 2;
string fileName = string.Join(
".",
elements.Skip(elements.Length - NumberOfFileNameElements));
string path = string.Join(
".",
elements.Take(elements.Length - NumberOfFileNameElements));
This assumes that the file name part only contains a single . character, so to get it you skip the number of remaining elements.
You can either use a Regex or String.Split with '.' as the separator and return the second-to-last + '.' + last pieces.
You can look for IndexOf("MyLibrary.Resources.Images.Properties."), add that to MyLibrary.Resources.Images.Properties.".Length and then .Substring(..) from that position
If you know exactly what you're looking for, and it's trailing, you could use string.endswith. Something like
if("MyLibrary.Resources.Images.Properties.Condo.gif".EndsWith("Condo.gif"))
If that's not the case check out regular expressions. Then you could do something like
if(Regex.IsMatch("Condo.gif"))
Or a more generic way: split the string on '.' then grab the last two items in the array.
string input = "MyLibrary.Resources.Images.Properties.legend.House.gif";
//if string isn't already validated, make sure there are at least two
//periods here or you'll error out later on.
int index = input.LastIndexOf('.', input.LastIndexOf('.') - 1);
string first = input.Substring(0, index);
string second = input.Substring(index + 1);
Try splitting the string into an array, by separating it by each '.' character.
You will then have something like:
{"MyLibrary", "Resources", "Images", "Properties", "legend", "House", "gif"}
You can then take the last two elements.
Just break down and do it in a char loop:
int NthLastIndexOf(string str, char ch, int n)
{
if (n <= 0) throw new ArgumentException();
for (int idx = str.Length - 1; idx >= 0; --idx)
if (str[idx] == ch && --n == 0)
return idx;
return -1;
}
This is less expensive than trying to coax it using string splitting methods and isn't a whole lot of code.
string s = "1.2.3.4.5";
int idx = NthLastIndexOf(s, '.', 3);
string a = s.Substring(0, idx); // "1.2"
string b = s.Substring(idx + 1); // "3.4.5"

Extracting values from a string in C#

I have the following string which i would like to retrieve some values from:
============================
Control 127232:
map #;-
============================
Control 127235:
map $;NULL
============================
Control 127236:
I want to take only the Control . Hence is there a way to retrieve from that string above into an array containing like [127232, 127235, 127236]?
One way of achieving this is with regular expressions, which does introduce some complexity but will give the answer you want with a little LINQ for good measure.
Start with a regular expression to capture, within a group, the data you want:
var regex = new Regex(#"Control\s+(\d+):");
This will look for the literal string "Control" followed by one or more whitespace characters, followed by one or more numbers (within a capture group) followed by a literal string ":".
Then capture matches from your input using the regular expression defined above:
var matches = regex.Matches(inputString);
Then, using a bit of LINQ you can turn this to an array
var arr = matches.OfType<Match>()
.Select(m => long.Parse(m.Groups[1].Value))
.ToArray();
now arr is an array of long's containing just the numbers.
Live example here: http://rextester.com/rundotnet?code=ZCMH97137
try this (assuming your string is named s and each line is made with \n):
List<string> ret = new List<string>();
foreach (string t in s.Split('\n').Where(p => p.StartsWith("Control")))
ret.Add(t.Replace("Control ", "").Replace(":", ""));
ret.Add(...) part is not elegant, but works...
EDITED:
If you want an array use string[] arr = ret.ToArray();
SYNOPSYS:
I see you're really a newbie, so I try to explain:
s.Split('\n') creates a string[] (every line in your string)
.Where(...) part extracts from the array only strings starting with Control
foreach part navigates through returned array taking one string at a time
t.Replace(..) cuts unwanted string out
ret.Add(...) finally adds searched items into returning list
Off the top of my head try this (it's quick and dirty), assuming the text you want to search is in the variable 'text':
List<string> numbers = System.Text.RegularExpressions.Regex.Split(text, "[^\\d+]").ToList();
numbers.RemoveAll(item => item == "");
The first line splits out all the numbers into separate items in a list, it also splits out lots of empty strings, the second line removes the empty strings leaving you with a list of the three numbers. if you want to convert that back to an array just add the following line to the end:
var numberArray = numbers.ToArray();
Yes, the way exists. I can't recall a simple way for It, but string is to be parsed for extracting this values. Algorithm of it is next:
Find a word "Control" in string and its end
Find a group of digits after the word
Extract number by int.parse or TryParse
If not the end of the string - goto to step one
realizing of this algorithm is almost primitive..)
This is simplest implementation (your string is str):
int i, number, index = 0;
while ((index = str.IndexOf(':', index)) != -1)
{
i = index - 1;
while (i >= 0 && char.IsDigit(str[i])) i--;
if (++i < index)
{
number = int.Parse(str.Substring(i, index - i));
Console.WriteLine("Number: " + number);
}
index ++;
}
Using LINQ for such a little operation is doubtful.

Parse Text Row with Empty Spaces

I have a file, the text format is like this:
.640 .070 -.390 -.740 -1.030 -1.410 -1.780 -1.840
-1.360 -.360 .860 1.880 2.340 2.250 1.950 1.710
1.410 .700 -.300 -.840 -.280 1.020 1.860 1.460
.310 -.460 -.320 .350 1.020 1.650 2.430 3.070
2.840 1.440 -.460 -1.650 -1.520 -.520 .250 .190
-.420 -.870 -.800 -.280 .570 1.660 2.500 2.220
.520 -1.560 -2.530 -2.030 -1.200 -1.060 -1.230 -.600
.990 2.300 2.180 .940 -.090 -.140 .320 .470
.330 .420 .830 1.080 1.090 1.530 2.740 3.800
3.410 1.610 -.150 -.900 -1.120 -1.640 -2.140 -1.590
.210 2.210 3.290 3.170 2.380 1.880 2.530 4.210
5.280 3.820 -.040 -3.670 -4.190 -1.260 2.930 5.740
5.980 3.920 .540 -2.890 -5.010 -4.780 -2.150 1.640
4.670 5.540 4.230 1.950 .120 -.470 -.010 .340
-.710 -2.940 -4.070 -1.810 3.000 6.590 6.140 2.750
-.490 -2.460 -4.180 -5.660 -4.800 -.560 4.510 6.630
5.140 2.860 2.230 2.510 1.670 -.440 -2.030 -2.330
Note that there are a lot of white characters between one value and another.
I tried to read each line, and then split the line according to a ' ' character. My code is something like this:
public List<double> Parse(StreamReader sr)
{
var dataList = new List<double>();
while (sr.Peek() >= 0)
{
string line = sr.ReadLine();
if (lineCount > 1)
{
string[] columns = line.Split(' ');
for (var j = 0; j < columns.Length; j++)
{
dataList.Add(double.Parse(columns[j]) ));
}
}
}
return dataList ;
}
The problem with the above code is that it is only able to handle the case where values are separated by a single white character.
Any idea ?
The simplest way is probably to use an overload of String.Split which includes a StringSplitOptions parameter, and specify StringSplitOptions.RemoveEmptyEntries.
I would also personally just call ReadLine until that returned null, rather than using TextReader.Peek. Aside from anything else, it's more general - it will work even if the underlying stream (if any) doesn't support seeking.
Before you do the split, replace all multi spaces with a single space, something like:
line = System.Text.RegularExpressions.Regex.Replace(line, #" +", #" ");
You may use the simple one line code for this. Let your text is in the string named input.
string[] values = System.Text.RegularExpressions.Regex.Split(input, #"\s+");
You will get all values in a string array simply

Help me delete the last three chars of any string please!

Test string:
the%20matrix%20
How can I delete the last three chars? Using this code gives me an out of index exception:
y = y.Substring(y.Length - 4, y.Length - 1);
Seems this isn't your REAL problem; if you want to remove that "%20", you should use:
string test = "the%20matrix%20";
string clean = HttpUtility.UrlDecode(test);
if (clean.Length > 2) // if you still want to strip last chars...
clean = clean.Substring(0, clean.Length - 3);
As dalovega said, you need the first parameter of Substring to be 0 and the second Length - 3. As an alternative:
if(y.Length >= 3)
{
y = y.Remove(y.Length - 3)
}
You want
y.Substring(0, y.Length-4)
If you want to delete the last three characters, you need the first parameter of your Substring method to be zero.
You need to check that the string is at least 3 characters long first.
if (y.Length > 2)
{
}
As others have said the version of Substring you want parameters are startIndex and length.
Though what do you want to do with 1 or 2 character strings?
I found this post from a search I was looking for. I had a delimiter I was building with a string builder, and concat and wanted to remove the last delimiter.
var delim = "{somedelimiter}";
var sb = new StringBuilder();
//concat the values into one string
foreach (var val in values)
{
sb.Append(val);
sb.Append(delim);
}
var finalValue = sb.ToString();
finalValue = finalValue.Remove(finalValue.Length - delim.Length);
string.Remove(string.LastIndexOf(" stringTo "));

Categories