Extract field value - c#

How to extract User-Name value from strings below with Regex:
Acc sfjlsf56 1 0 User-Name=User_1, Group-Name=DCN_VPN_Support,
must be User_1
Acc t3we89ab 1 0 User-Name=John,Group-Name=DCN_VPN_Support,
must be John
Acc y5g769bo 1 0 User-Name=,Group-Name=DCN_VPN_Support,
must be null

To extract the username, we look for the User-Name= token, then match all characters after it that aren't a , (which denotes the next element). We tag this matched group with the name "username" to retrieved it later:
User-Name=(?<username>[^,]*)
var match = Regex.Match(stringToMatch, "User-Name=(?<username>[^,]*)");
string username = match.Success ? match.Groups["username"].Value : null;
Note that this will match the empty user as "" (String.Empty) rather than null. If null is required, simply translate it afterwards.

I believe the User-Name=[a-z\d]*, you can use

Related

Get the value using substr and instr in oracle

I have following value in the table.
aaaaaa 26G 2.0G 23G 8 tmp
tmpfs 506M 0 506M 0 /dev/shm
I need to store first value that is ('aaaaaa' and'tmpfs') and second value (26 and 506) in another table. I got first value by
CAST(substr(COL_1,1,InStr(COL_1,' ')-1) AS VARCHAR2(10)) col
How do I get the second value such as 26 and 506 using substring and instring.?
I would recommend regexp_substr():
select regexp_substr(col1, '[^ ]+ ', 1, 1) as first,
regexp_substr(col1, '[^ ]+ ', 1, 2) as second
This returns the value with a space at the end. I think the pattern works without the space, because regular expression matching is greedy in Oracle:
select regexp_substr(col1, '[^ ]+', 1, 1) as first,
regexp_substr(col1, '[^ ]+', 1, 2) as second
There is an optional argument to instr where you can specify the nth occurrence of a specific string being searched.
CAST(substr(COL_1,InStr(COL_1,' ',1,1)+1,InStr(COL_1,' ',1,2)-InStr(COL_1,' ',1,1)-1) AS VARCHAR2(10))
To only extract the number from this substring, use regexp_substr. This assumes letters always follow one or more numeric characters.
regexp_substr(CAST(substr(COL_1,InStr(COL_1,' ',1,1)+1,InStr(COL_1,' ',1,2)-InStr(COL_1,' ',1,1)-1) AS VARCHAR2(10)),'\d+')

C# - Getting multiple values with a single key, from a text file

I store multiple values that shares a single key on a text file. The text file looks like that:
Brightness 36 , Manual
BacklightCompensation 3 , Manual
ColorEnable 0 , None
Contrast 16 , Manual
Gain 5 , Manual
Gamma 122 , Manual
Hue 0 , Manual
Saturation 100 , Manual
Sharpness 2 , Manual
WhiteBalance 5450 , Auto
Now I want to store the int value & string value of each key (Brightness, for example).
New to C# and could'nt find something that worked yet.
Thanks
I'd recommend to use custom types to store these settings like these:
public enum DisplaySettingType
{
Manual, Auto, None
}
public class DisplaySetting
{
public string Name { get; set; }
public decimal Value { get; set; }
public DisplaySettingType Type { get; set; }
}
Then you could use following LINQ query using string.Split to get all settings:
decimal value = 0;
DisplaySettingType type = DisplaySettingType.None;
IEnumerable<DisplaySetting> settings = File.ReadLines(path)
.Select(l => l.Trim().Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries))
.Where(arr => arr.Length >= 3 && decimal.TryParse(arr[1], out value) && Enum.TryParse(arr[2], out type))
.Select(arr => new DisplaySetting { Name = arr[0], Value = value, Type = type });
With a regex and a little bit of linq you can do many things.
Here I assume you Know How to read a Text file.
Pros: If the file is not perfect, the reg exp will just ignore the misformatted line, and won't throw error.
Here is a hardcode version of your file, note that a \r will appears because of it. Depending on the way you read you file but it should not be the case with a File.ReadLines()
string input =
#"Brightness 36 , Manual
BacklightCompensation 3 , Manual
ColorEnable 0 , None
Contrast 16 , Manual
Gain 5 , Manual
Gamma 122 , Manual
Hue 0 , Manual
Saturation 100 , Manual
Sharpness 2 , Manual
WhiteBalance 5450 , Auto";
string regEx = #"(.*) (\d+) , (.*)";
var RegexMatch = Regex.Matches(input, regEx).Cast<Match>();
var outputlist = RegexMatch.Select(x => new { setting = x.Groups[1].Value
, value = x.Groups[2].Value
, mode = x.Groups[3].Value });
Regex explanation:/(.*) (\d+) , (.*)/g
1st Capturing Group (.*)
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
matches the character literally (case sensitive)
2nd Capturing Group (\d+)
\d+ matches a digit (equal to [0-9])
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
, matches the characters , literally (case sensitive)
3rd Capturing Group (.*)
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
Disclamer:
Never trust an input! Even if it's a file some other program did, or send by a customer.
From my experience, you have then two ways of handeling bad format:
Read line by line, and register every bad line.
or Ignore them. You don't fit , you don't sit!
And don't tell your self it won't happend, it will!

Regex condition in C#

I have state numbers and state letters of vehicles according to States in DB. State numbers can be old and new type.
Example of new types of state number.
273KL01
002UK02
098KZ03
120US04
...
Example of old types of state number.
R575KMM
A887KDN
M784LKA
X647DUA
...
Bold characters indicates specified State.
User will input his car's state number and choose State. I need to validate If state number can be registered in chosen State. If it not possible(wrong user input) I will show him message like "You entered wrong state number or State" .
I have done this with If-Else statement. But I want to know another way with regex.
As I think, here will be two steps of condition.
Check if number is old type(starts with letter), if true get from DB state letter and check with regex statements.
If case 1 is false, I get from DB state digits and check with regex statements.
I have regex statement for the first condition:
^(?i)f - Where state letter is f.
What will be regex statement for my second conditon?
Or can be it done(two steps both) with one regex statements?
As you further explained that you actually do want to match any letter at the beginning, and any two digits at the end of the string, using a regular expression is indeed the shortest way to solve this.
Regex re = new Regex("^[a-z].*[0-9]{2}$", RegexOptions.IgnoreCase);
Console.WriteLine(re.IsMatch("Apple02")); // true
Console.WriteLine(re.IsMatch("Arrow")); // false
Console.WriteLine(re.IsMatch("45Alty12")); // false
Console.WriteLine(re.IsMatch("Basci98")); // true
Otherwise, if your requirement is simple, e.g. just the letter A or a at the beginning, and 12 or 02 at the end, then you can also solve this easily without regular expressions:
bool Match(string s)
{
if (string.IsNullOrWhiteSpace(s))
return false;
if (s[0] != 'a' && s[0] != 'A')
return false;
return s.EndsWith("02") || s.EndsWith("12");
}
Examples:
Console.WriteLine(Match("Apple02")); // true
Console.WriteLine(Match("Arrow")); // false
Console.WriteLine(Match("45Alty12")); // false
Console.WriteLine(Match("a12")); // true
Console.WriteLine(Match("a")); // false
Console.WriteLine(Match("12")); // false
Of course you can also expand this to fit your more complex requirement. In your case, you could use char.IsLetter and char.IsDigit to make the checks:
bool Match(string s)
{
if (string.IsNullOrWhiteSpace(s))
return false;
return s.Length > 2 && char.IsLetter(s[0]) &&
char.IsDigit(s[s.Length - 1]) && char.IsDigit(s[s.Length - 2]);
}
Note that the IsLetter method also accepts letters from non-English alphabets, so you might need to change that. You could alternatively make a comparison like this:
bool Match(string s)
{
if (string.IsNullOrWhiteSpace(s))
return false;
return s.Length > 2 &&
((s[0] >= 'a' && s[0] <= 'z') || (s[0] >= 'A' && s[0] <= 'Z'))
char.IsDigit(s[s.Length - 1]) && char.IsDigit(s[s.Length - 2]);
}
Here's what you need:
^[Aa].*[01][2]$
With a few explanations:
^ assert position at start of a line
[Aa] match a single character present in the list below
Aa a single character in the list Aa literally
.* matches any character (except newline)
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
[01] match a single character present in the list below
01 a single character in the list 01 literally
[2] match a single character present in the list below
2 the literal character 2
$ assert position at end of a line
If you need it to start with any letter :
^[A-Za-z].*[01][2]$
Given your edit:
I would use this regex:
^[A-Z].{6}|.{5}\d{2}$
Which guaranties that the input is:
Of length 7;
Start with a capital letter OR finishes with two digit

Filtering on full string match but not on substrings

So I've got a long string of numbers and characters and I'd like to filter out a substring. The thing I'm struggling with is that I need a full match on a certain value (starting with S) but this may not be matched in another value.
Input:
S10 1+0000000297472+00EURS100 1+0000000297472+00EURS1023P 1+0000000816072+00EUR
The input is exactly like this.
Breakdown of input:
S10 1+0000000297472+00EUR
Every part starts with a tag S and ends with EUR
There are spaces in between because every part has a fixed length
=>
index 0 : tag 'S' with length 1
index 1 : code with length 7
index 8 : numbertype with length 1
index 9 : sign with length 1
index 10 : value with length 13
index 23 : sign with length 1
index 24 : exponent with length 2
index 26 : unit with length 3
I need to match on for example S10 and I only want this substring till EUR. I don't want it to match on S100 or S1023P or any other combination. Only on exactly S10
Output:
S10 1+0000000297472+00EUR
I'm trying to use Regex to find my match on 'S + code'. I'm doing a full match on my search query and then as soon as anything follows I don't want it anymore. But doing it like this also discards the actual match as after the S10 the value will follow which will match with [^\d|^\D])+\w
foreach (var field in fieldList)
{
var query = "S" + field.BallanceCode;
var index = Regex.Match(values, Regex.Escape(query) + #"([^\d|^\D])+\w").Index;
}
For example when looking for S10
needs to match:
S10 1+0000000297472+00EUR
may not match:
S10/15 1+0000001748447+00EUR
S1023P 1+0000000816072+00EUR
S10000001+0000000546546+00EUR
Update:
Using this code
var index = Regex.Match(values, Regex.Escape(query) + #"\p{Zs}.*?EUR").Index;
wil yield S10, S10/15, etc when looked for. However looking for S1000000 in the string doesn't work because there is no whitespace between the code and 1+
S10000001+0000000546546+00EUR
For example when looking for S1000000
needs to match:
S10000001+0000000297472+00EUR
may not match:
S10 1+0000001748447+00EUR
S1023P 1+0000000816072+00EUR
S10/15 1+0000000546546+00EUR
You can use a regex that requires a space (or whitespace) to appear right after the field.BallanceCode:
var index = Regex.Match(values, Regex.Escape(query) + (field.BallanceCode.Length < 7 ? #"\p{Zs}" : "") + ".*?EUR").Index;
The regex will match the S10, then any horizontal whitespace (\p{Zs}), then any 0 or more characters other than a newline (as few as possible due to *?) up to the first EUR.
The (field.BallanceCode.Length < 7 ? #"\p{Zs}" : "") check is necessary to support a 7-digit BallanceCode. If it contains 7 digits or more, we do not check if there is a whitespace after it. If the length is less than 7, we check for a space.
So you just want the start (S...) and end (...EUR) of each line and skip everything in between?
^([sS]\d+).*?([\d\+]+EUR)$
http://regexr.com/3c1ob

C# Regex.IsMatch returns true when it shouldn't?

I'm attempting to match a string that can contain any number of numeric characters or a decimal point using the following regex:
([0-9.])*
Here's some C# code to test the regex:
Regex regex = new Regex("([0-9.])*");
if (!regex.IsMatch("a"))
throw new Exception("No match.");
I expect the exception to be thrown here but it isn't - am I using the Regex incorrectly or is there an error in the pattern?
EDIT: I'd also like to match a blank string.
The * quantifier means "match 0 or more". In your case, "a" returns 0 matches, so the regex still succeeds. You probably wanted:
([0-9.]+)
The + quantifier means "match 1 or more, so it fails on non-numeric inputs and returns no matches. A quick spin the regex tester shows:
input result
----- ------
[empty] No matches
a No matches
. 1 match: "."
20.15 1 match: "20.15"
1 1 match: "1"
1.1.1 1 match: "1.1.1"
20. 1 match: "20."
Looks like we have some false positives, let's revise the regex as such:
^([0-9]+(?:\.[0-9]+)?)$
Now we get:
input result
----- ------
[empty] No matches
a No matches
. No matches
20.15 1 match: "20.15"
1 1 match: "1"
1.1.1 No matches: "1.1.1"
20. No matches
Coolness.
Regex.IsMatch("a", "([0-9.])*") // true
This is because the group can match ZERO or more times.
Regex.IsMatch("a", "([0-9.])+") // false
You should use + instead of *
Regex reg = new Regex("([0-9.])+");
This should work fine.
When you use * any string can match this pattern in your case.

Categories

Resources