How do I Split the string into two separate variables in C# - c#

I have a string that I want to store in two different varaibles in C#.
s= "Name=team1; ObjectGUID=d8fd5125-b065-48cb-b5f3-c20f509b7476"
I want Var1 = team1 & Var2 = d8fd5125-b065-48cb-b5f3-c20f509b7476
Here's what I am trying to do:
var1 = s.Replace("Name=","").Replace("; ObjectGUID=", "");
But I am not able to figure out how to bifurcate the Name value to var1 and eliminate the rest. And it is possible that the value of 'Name' could vary so I can't fix the length to chop off.

You could use a regex where the value of Name could be captured in group 1 matching not a ; using a negated character class.
The value of ObjectGUID could be captured in group 2 using a repeated pattern matching 1+ times a digit 0-9 or characters a-f. Then repeat that pattern 1+ times preceded with a -
Name=([^;]+); ObjectGUID=([a-f0-9]+(?:-[a-f0-9]+)+)
.NET regex demo | C# demo
For example:
string pattern = #"Name=([^;]+); ObjectGUID=([a-f0-9]+(?:-[a-f0-9]+)+)";
string s= "Name=team1; ObjectGUID=d8fd5125-b065-48cb-b5f3-c20f509b7476";
Match m = Regex.Match(s, pattern);
string var1 = m.Groups[1].Value;
string var2 = m.Groups[2].Value;
Console.WriteLine(var1);
Console.WriteLine(var2);
Result
team1
d8fd5125-b065-48cb-b5f3-c20f509b7476

Split by ';' then split by '='. Also works for any key/value pairs such as the ones in connection strings.
var values = s.Split(';').Select(kv => kv.Split('=')[1]).ToArray();
var var1 = values[0];
var val2 = values[1];

You can use IndexOf to take point at "=" and Substring to take the next value.
using System;
public class SubStringTest {
public static void Main() {
string [] info = { "Name: Felica Walker", "Title: Mz.",
"Age: 47", "Location: Paris", "Gender: F"};
int found = 0;
Console.WriteLine("The initial values in the array are:");
foreach (string s in info)
Console.WriteLine(s);
Console.WriteLine("\nWe want to retrieve only the key information. That
is:");
foreach (string s in info) {
found = s.IndexOf(": ");
Console.WriteLine(" {0}", s.Substring(found + 2));
}
}
}
The example displays the following output:
The initial values in the array are:
Name: Felica Walker
Title: Mz.
Age: 47
Location: Paris
Gender: F
We want to retrieve only the key information. That is:
Felica Walker
Mz.
47
Paris
F

Related

Regex to find all placeholder occurrences in text

Im struggling to create a Regex that finds all placeholder occurrences in a given text. Placeholders will have the following format:
[{PRE.Word1.Word2}]
Rules:
Delimited by "[{PRE." and "}]" ("PRE" upper case)
2 words (at least 1 char long each) separated by a dot. All chars valid on each word apart from newline.
word1: min 1 char, max 15 chars
word2: min 1 char, max 64 chars
word1 cannot have dots, if there are more than 2 dots inside placeholder extra ones will be part of word2. If less than 2 dots, placeholder is invalid.
Looking to get all valid placeholders regardless of what the 2 words are.
Im not being lazy, just spent an horrible amount of time building the rule on regexr.com, but was unable to cross all these rules.
Looking fwd to checking your suggestions.
The closest I've got to was the below, and any attempt to expand on that breaks all valid matches.
\[\{OEP\.*\.*\}\]
Much appreciated!
Sample text where Regex should find matches:
Random text here
[{Test}] -- NO MATCH
[{PRE.TestTest3}] --NO MATCH
[{PRE.TooLong.12345678901234567890}] --NO MATCH
[{PRE.Address.Country}] --MATCH
[{PRE.Version.1.0}] --MATCH
Random text here
You can use
\[{PRE\.([^][{}.]{1,15})\.(.{1,64}?)}]
See the regex demo
Details
\[{ - a [{ string
PRE\. - PRE. text
([^][{}.]{1,15}) - Group 1: any one to fifteen chars other than [, ], {, } and .
\. - a dot
(.{1,64}?) - any one to 64 chars other than line break chars as few as possible
}] - a }] text.
If you need to get all matches in C#, you can use
var pattern = #"\[{PRE\.([^][{}.]{1,15})\.(.{1,64}?)}]";
var matches = Regex.Matches(text, pattern);
See this C# demo:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
var text = "[{PRE.Word1.Word2}] and [{PRE.Word 3.Word..... 2 %%%}]";
var pattern = #"\[{PRE\.([^][{}.]{1,15})\.(.{1,64}?)}]";
var matches = Regex.Matches(text, pattern);
var props = new List<Property>();
foreach (Match m in matches)
props.Add(new Property(m.Groups[1].Value,m.Groups[2].Value));
foreach (var item in props)
Console.WriteLine("Word1 = " + item.Word1 + ", Word2 = " + item.Word2);
}
public class Property
{
public string Word1 { get; set; }
public string Word2 { get; set; }
public Property()
{}
public Property(string w1, string w2)
{
this.Word1 = w1;
this.Word2 = w2;
}
}
}
Output:
Word1 = Word1, Word2 = Word2
Word1 = Word 3, Word2 = Word..... 2 %%%
string input = "[{PRE.Word1.Word2}]";
// language=regex
string pattern = #"\[{ PRE \. (?'group1' .{1,15}? ) \. (?'group2' .{1,64}? ) }]";
var match = Regex.Match(input, pattern, RegexOptions.IgnorePatternWhitespace);
Console.WriteLine(match.Groups["group1"].Value);
Console.WriteLine(match.Groups["group2"].Value);

Get particular field or characters from string line in C#

I have one file and read file line by line and extract particular object from string line.
for example string line is in two format.
VA001748714600006640126132202STRONG 4P 4X44G000099
VA 00174 871460000664 012 6132202 STRONG 4P 4X44G 000099
now i need to extract string and store into my table and fields like below and above two line data generate in below fields(Desire Results).
Code Location SerialNo Quantity ItemNo Description Price
VA 00174 871460000664 12 6132202 STRONG 4P 4X44G0 000099
what i have tried. i have created one method that return object[] extract from string
public static object[] ProcessLine(string line)
{
var obj = new object[7];
var str = line.Replace("\0", "").Replace(" ", "");
string code = str.Substring(0, 2)?.Trim();
string location = str.Substring(2, 5)?.Trim();
string serialNo = str.Substring(7, 12)?.Trim();
string quantity = str.Substring(19, 3)?.Trim();
int qty = 0;
if (!string.IsNullOrEmpty(quantity))
{
qty = Convert.ToInt32(quantity);
}
string itemNo = str.Substring(22, 7)?.Trim();
Regex MyRegex = new Regex("[^a-z ]", RegexOptions.IgnoreCase);
string description = MyRegex.Replace(line.Substring(2), #"")?.Trim();
string price = str.Substring(str.Length - 6)?.Trim();
obj.SetValue(code, 0);
obj.SetValue(location, 1);
obj.SetValue(serialNo, 2);
obj.SetValue(qty, 3);
obj.SetValue(itemNo, 4);
obj.SetValue(description, 5);
obj.SetValue(price, 6);
return obj;
}
i have find sub-string and store into object, also i can't find Description because this field is not fixed letters.
(Code,Location,SerialNo,Quantity,ItemNo and Price) are fixed no.of characters and (Description) fields are any characters or changes.
how to find this fields value and description using regex i tried to find description but it extract without digit.
If you really want to use a regex, see Wiktor's answer.
However, you don't need a regex for this problem.
Since all fields except description have known lengths, you can calculate the length of the description field. From your specs the description starts at position 29, and is followed by 6 positions for the price field. Therefore, this should give you the description:
string description = str.Substring(29, str.Length-29-6);
You may declare a regex like
private static readonly Regex rx = new Regex(#"^(\w{2})\s*(\w{5})\s*(\w{12})\s*(\d{3})\s*(\d{7})\s*(.*?)\s*(\d{6})$", RegexOptions.Compiled);
See the regex demo.
The point is to use a regex that matches a whole string (^ match the start of a string and $ matches the end of the string), use \w (any letter/digit/_ chars) or \d (any digit char), {m} quantifier to match a certain amount of the chars matched with \w or \d, match the Description field with .*?, a lazy dot pattern that matches any 0+ chars other than newline as few as possible, and allow any 0+ whitespace chars in between fields with \s*.
Then, you may use it
public static object[] ProcessLine(string line)
{
object[] obj = null;
var m = rx.Match(line);
if (m.Success)
{
obj = new object[] {
m.Groups[1].Value,
m.Groups[2].Value,
m.Groups[3].Value,
int.Parse(m.Groups[4].Value).ToString(), // remove leading zeros
m.Groups[5].Value,
m.Groups[6].Value,
m.Groups[7].Value
};
}
return obj;
}
See the C# demo, demo output for both the strings in OP:
VA, 00174, 871460000664, 12, 6132202, KING PEPERM E STRONG 4P 4X44G, 000099
VA, 00174, 871460000664, 12, 6132202, KING PEPERM E STRONG 4P 4X44G, 000099

Splitting a string at first number and then returning 2 strings

Having some trouble adapting my splitting of a string into 2 parts to do it from the first number. It's currently splitting on the first space, but that won't work long term because cities have spaces in them too.
Current code:
var string = "Chicago 1234 Anytown, NY"
var commands = parameters.Split(new[] { ' ' }, 2);
var originCity = commands[0];
var destination = commands[1];
This works great for a city that has a single name, but I break on:
var string = "Los Angeles 1234 Anytown, NY"
I've tried several different approaches that I just haven't been able to work out. Any ideas on being able to return 2 strings as the following:
originCity = Los Angeles
destination = 1234 Anytown, NY
You can't use .Split() for this.
Instead, you need to find the index of the first number. You can use .indexOfAny() with an array of numbers (technically a char[] array) to do this.
int numberIndex = address.IndexOfAny("0123456789".ToCharArray())
You can then capture two substrings; One before the index, the other after.
string before = line.Substring(0, numberIndex);
string after = line.Substring(numberIndex);
You could use Regex. In the following, match is the first match in the regex results.
var match = Regex.Match(s, "[0-9]");
if (match.Success)
{
int index = match.Index;
originCity = s.Substring(0, index);
destination = s.Substring(index, s.Length - index);
}
Or you can do it yourself:
int index = 0;
foreach (char c in s)
{
int result;
if (int.TryParse(c, out result))
{
index = result;
break;
}
//or if (char.IsDigit()) { index = int.Parse(c); break; }
}
...
You should see if using a regular expression will do what you need here. At least with the sample data you're showing, the expression:
(\D+)(\d+)(\D+)
would group the results into non-numeric characters up to the first numeric character, the numeric characters until a non-numeric is encountered, and then the rest of the non-numeric characters. Here is how it would be used in code:
var pattern = #"(\D+)(\d+)(\D+)";
var input = "Los Angeles 1234 Anytown, NY";
var result = Regex.Match(input, pattern);
var city = result.Groups[1];
var destination = $"{result.Groups[2]} {result.Groups[3]}";
This falls apart in cases like 29 Palms, California or if the numbers would contain comma, decimal, etc so it is certainly not a silver bullet but I don't know your data and it may be ok for such a simple solution.

how do i replace exact phrases in c# string.replace

I am trying to ensure that a list of phrases start on their own line by finding them and replacing them with \n + the phrase. eg
your name: joe your age: 28
becomes
my name: joe
your age: 28
I have a file with phrases that i pull and loop through and do the replace. Except as there are 2 words in some phrases i use \b to signify where the phrase starts and ends.
This doesn't seem to work, anybody know why?
example - String is 'Name: xxxxxx' does not get edited.
output = output.Replace('\b' + "Name" + '\b', "match");
Using regular expressions, accounts for any number of words with any number of spaces:
using System.Text.RegularExpressions;
Regex re = new Regex("(?<key>\\w+(\\b\\s+\\w+)*)\\s*:\\s*(?<value>\\w+)");
MatchCollection mc = re.Matches("your name: joe your age: 28 ");
foreach (Match m in mc) {
string key = m.Groups("key").Value;
string value = m.Groups("value").Value;
//accumulate into a list, but I'll just write to console
Console.WriteLine(key + " : " + value);
}
Here is some explanation:
Suppose what you want to the left of the colon (:) is called a key, and what is to the right - a value.
These key/value pairs are separated by at least once space. Because of this, value has be exactly one word (otherwise we'd have ambiguity).
The above regular expression uses named groups, to make code more readable.
got it
for (int headerNo=0; headerNo<headersArray.Length; headerNo++)
{
string searchPhrase = #"\b" + PhraseArray[headerNo] + #"\b";
string newPhrase = "match";
output = Regex.Replace(output, searchPhrase, newPhrase); }
Following the example you can do that :
output = output.Replace("your", "\nyour");

what regex must i use to split this?

i am very newbie to c#..
i want program if input like this
input : There are 4 numbers in this string 40, 30, and 10
output :
there = string
are = string
4 = number
numbers = string
in = string
this = string
40 = number
, = symbol
30 = number
, = symbol
and = string
10 = number
i am try this
{
class Program
{
static void Main(string[] args)
{
string input = "There are 4 numbers in this string 40, 30, and 10.";
// Split on one or more non-digit characters.
string[] numbers = Regex.Split(input, #"(\D+)(\s+)");
foreach (string value in numbers)
{
Console.WriteLine(value);
}
}
}
}
but the output is different from what i want.. please help me.. i am stuck :((
The regex parser has an if conditional and the ability to group items into named capture groups; to which I will demonstrate.
Here is an example where the patttern looks for symbols first (only a comma add more symbols to the set [,]) then numbers and drops the rest into words.
string text = #"There are 4 numbers in this string 40, 30, and 10";
string pattern = #"
(?([,]) # If a comma (or other then add it) is found its a symbol
(?<Symbol>[,]) # Then match the symbol
| # else its not a symbol
(?(\d+) # If a number
(?<Number>\d+) # Then match the numbers
| # else its not a number
(?<Word>[^\s]+) # So it must be a word.
)
)
";
// Ignore pattern white space allows us to comment the pattern only, does not affect
// the processing of the text!
Regex.Matches(text, pattern, RegexOptions.IgnorePatternWhitespace)
.OfType<Match>()
.Select (mt =>
{
if (mt.Groups["Symbol"].Success)
return "Symbol found: " + mt.Groups["Symbol"].Value;
if (mt.Groups["Number"].Success)
return "Number found: " + mt.Groups["Number"].Value;
return "Word found: " + mt.Groups["Word"].Value;
}
)
.ToList() // To show the result only remove
.ForEach(rs => Console.WriteLine (rs));
/* Result
Word found: There
Word found: are
Number found: 4
Word found: numbers
Word found: in
Word found: this
Word found: string
Number found: 40
Symbol found: ,
Number found: 30
Symbol found: ,
Word found: and
Number found: 10
*/
Once the regex has tokenized the resulting matches, then we us linq to extract out those tokens by identifying which named capture group has a success. In this example we get the successful capture group and project it into a string to print out for viewing.
I discuss the regex if conditional on my blog Regular Expressions and the If Conditional for more information.
You could split using this pattern: #"(,)\s?|\s"
This splits on a comma, but preserves it since it is within a group. The \s? serves to match an optional space but excludes it from the result. Without it, the split would include the space that occurred after a comma. Next, there's an alternation to split on whitespace in general.
To categorize the values, we can take the first character of the string and check for the type using the static Char methods.
string input = "There are 4 numbers in this string 40, 30, and 10";
var query = Regex.Split(input, #"(,)\s?|\s")
.Select(s => new
{
Value = s,
Type = Char.IsLetter(s[0]) ?
"String" : Char.IsDigit(s[0]) ?
"Number" : "Symbol"
});
foreach (var item in query)
{
Console.WriteLine("{0} : {1}", item.Value, item.Type);
}
To use the Regex.Matches method instead, this pattern can be used: #"\w+|,"
var query = Regex.Matches(input, #"\w+|,").Cast<Match>()
.Select(m => new
{
Value = m.Value,
Type = Char.IsLetter(m.Value[0]) ?
"String" : Char.IsDigit(m.Value[0]) ?
"Number" : "Symbol"
});
Well to match all numbers you could do:
[\d]+
For the strings:
[a-zA-Z]+
And for some of the symbols for example
[,.?\[\]\\\/;:!\*]+
You can very easily do this like so:
string[] tokens = Regex.Split(input, " ");
foreach(string token in tokens)
{
if(token.Length > 1)
{
if(Int32.TryParse(token))
{
Console.WriteLine(token + " = number");
}
else
{
Console.WriteLine(token + " = string");
}
}
else
{
if(!Char.isLetter(token ) && !Char.isDigit(token))
{
Console.WriteLine(token + " = symbol");
}
}
}
I do not have an IDE handy to test that this compiles. Essentially waht you are doing is splitting the input on space and then performing some comparisons to determine if it is a symbol, string, or number.
If you want to get the numbers
var reg = new Regex(#"\d+");
var matches = reg.Matches(input );
var numbers = matches
.Cast<Match>()
.Select(m=>Int32.Parse(m.Groups[0].Value));
To get your output:
var regSymbols = new Regex(#"(?<number>\d+)|(?<string>\w+)|(?<symbol>(,))");
var sMatches = regSymbols.Matches(input );
var symbols = sMatches
.Cast<Match>()
.Select(m=> new
{
Number = m.Groups["number"].Value,
String = m.Groups["string"].Value,
Symbol = m.Groups["symbol"].Value
})
.Select(
m => new
{
Match = !String.IsNullOrEmpty(m.Number) ?
m.Number : !String.IsNullOrEmpty(m.String)
? m.String : m.Symbol,
MatchType = !String.IsNullOrEmpty(m.Number) ?
"Number" : !String.IsNullOrEmpty(m.String)
? "String" : "Symbol"
}
);
edit
If there are more symbols than a comma you can group them in a class, like #Bogdan Emil Mariesan did and the regex will be:
#"(?<number>\d+)|(?<string>\w+)|(?<symbol>[,.\?!])"
edit2
To get the strings with =
var outputLines = symbols.Select(m=>
String.Format("{0} = {1}", m.Match, m.MatchType));

Categories