C# Extracting a name from a string - c#

I want to extract 'James\, Brown' from the string below but I don't always know what the name will be. The comma is causing me some difficuly so what would you suggest to extract James\, Brown?
OU=James\, Brown,OU=Test,DC=Internal,DC=Net
Thanks

A regex is likely your best approach
static string ParseName(string arg) {
var regex = new Regex(#"^OU=([a-zA-Z\\]+\,\s+[a-zA-Z\\]+)\,.*$");
var match = regex.Match(arg);
return match.Groups[1].Value;
}

You can use a regex:
string input = #"OU=James\, Brown,OU=Test,DC=Internal,DC=Net";
Match m = Regex.Match(input, "^OU=(.*?),OU=.*$");
Console.WriteLine(m.Groups[1].Value);

A quite brittle way to do this might be...
string name = #"OU=James\, Brown,OU=Test,DC=Internal,DC=Net";
string[] splitUp = name.Split("=".ToCharArray(),3);
string namePart = splitUp[1].Replace(",OU","");
Console.WriteLine(namePart);
I wouldn't necessarily advocate this method, but I've just come back from a departmental Christmas lyunch and my brain is not fully engaged yet.

I'd start off with a regex to split up the groups:
Regex rx = new Regex(#"(?<!\\),");
String test = "OU=James\\, Brown,OU=Test,DC=Internal,DC=Net";
String[] segments = rx.Split(test);
But from there I would split up the parameters in the array by splitting them up manually, so that you don't have to use a regex that depends on more than the separator character used. Since this looks like an LDAP query, it might not matter if you always look at params[0], but there is a chance that the name might be set as "CN=". You can cover both cases by just reading the query like this:
String name = segments[0].Split('=', 2)[1];

That looks suspiciously like an LDAP or Active Directory distinguished name formatted according to RFC 2253/4514.
Unless you're working with well known names and/or are okay with a fragile hackaround (like the regex solutions) - then you should start by reading the spec.
If you, like me, generally hate implementing code according to RFCs - then hope this guy did a better job following the spec than you would. At least he claims to be 2253 compliant.

If the slash is always there, I would look at potentially using RegEx to do the match, you can use a match group for the last and first names.
^OU=([a-zA-Z])\,\s([a-zA-Z])
That RegEx will match names that include characters only, you will need to refine it a bit for better matching for the non-standard names. Here is a RegEx tester to help you along the way if you go this route.

Replace \, with your own preferred magic string (perhaps & #44;), split on remaining commas or search til the first comma, then replace your magic string with a single comma.
i.e. Something like:
string originalStr = #"OU=James\, Brown,OU=Test,DC=Internal,DC=Net";
string replacedStr = originalStr.Replace("\,", ",");
string name = replacedStr.Substring(0, replacedStr.IndexOf(","));
Console.WriteLine(name.Replace(",", ","));

Assuming you're running in Windows, use PInvoke with DsUnquoteRdnValueW. For code, see my answer to another question: https://stackoverflow.com/a/11091804/628981

If the format is always the same:
string line = GetStringFromWherever();
int start = line.IndexOf("=") + 1;//+1 to get start of name
int end = line.IndexOf("OU=",start) -1; //-1 to remove comma
string name = line.Substring(start, end - start);
Forgive if syntax is not quite right - from memory. Obviously this is not very robust and fails if the format ever changes.

Related

Regular expression to extract file name from p4 path

From path "//source/project/file.cs#232", I need to match file.cs
Match myMatch = Regex.Match(path, #"(\w+\.\w+)[^/]*$");
This would give file.cs in groups[1].
But for paths with dots in the file name, this doesn't work.
path "//source/project/file.initial.config.cs#232"
How could I modify this to work to give file.initial.config.cs?
Try this regex -- also into group 1, and assuming the extension can only be letters, numbers or the underscore:
.*/((?:.*?\.)+\w+)
This could be made more robust, if necessary, with knowledge of the allowable characters and suffixes for file naming, as well as details about the text in which (if) this file name is embedded. For example, if spaces were not allowed as part of the name
.*/((?:\S*?\.)+\w+)
or if ONLY letters, digits or the underscore are allowed:
.*/((?:\w*?\.)+\w+)
If we could be assured that there will be no dots or spaces after the last dot in the sequence, and spaces not allowed in the filename, it could be shortened further to:
.*/(\S*\.\w+)
to pick up everything between the last "/" and the last "." as well as any word characters after the last "."
etc
A number of non-'/' before '#':
/([^/]+)#
This should allow you to do what you want, or at least give you a better idea of how to achieve it:
/(\w+)(?:\..*)(\w{2,3})\#)
• example: http://regex101.com/r/wQ9jG2
Can you not simply modify your regex from (\w+\.\w+)[^/]*$ to (\w+(\.\w+)+)[^/]*$, to allow multiple occurrences of .words?
Why use regex, when you can do it in c# ?
I've created a function for you:
public static class FileNameHelper
{
public static string GetFileNameFromPath(string path, string extWithoutdot = "cs")
{
var startIndex = path.LastIndexOf('/') + 1;
var stringg = path.Substring(startIndex);
var remIndex = stringg.LastIndexOf("." + extWithoutdot) + extWithoutdot.Length+1;
return stringg.Remove(remIndex);
}
}
How to use ?
string filename=FileNameHelper.GetFileNameFromPath("//source/project/file.initial.config.cs#232","cs");
Remember to use the extension without .
See this has a lot of advantage over regex. They are:
Its not regex !
Its fast and efficient.
Its readable and pure c#
Note: Don't use regex in c# for trivial things. It's definitely a blow on the performance. First think of ways of achieving it in c#. Regex should be a last resort. Of course, if performance doesn't matter, use whatever !
By the way, mark it as answer if it helps. I know it'll help :)
If you're not averse to avoiding regular expressions, you could do this with just a small bit of string manipulation:
string mypath = "//source/project/file.initial.config.cs#232";
string filename = GetFileName(mypath);
static string GetFileName(string path)
{
var pathPieces = path.Split('/').Last().Split('#');
var filename = pathPieces.Take(pathPieces.Length - 1);
return String.Join("#", filename);
}
Easier, and works with any arbitrary filename (even those with spaces or # characters).
EDIT: Now works with filenames with # characters in them, although those are highly discouraged in Perforce.
(?<=/)[^/]+(?=#)
Using lookaround, it matches only the filename.

Correction in this simple regular expression

I am new to regular expressions and the one that i have written might be a very simple one but donot know where I am wrong.
#"^([a-zA-Z._]+)#([\d]+)"
This RE is for the following string:
somename#somenumber
Now i am trying to retrieve the somename and somenumber. This is what i did:
ac.name = m.Groups[0].Value;
ac.number = m.Groups[1].Value;
Here ac.name reads the complete string, and ac.number reads somenumber. Where am I wrong in ac.name?
i guess the regex is correct, the problem is, you get the ac.name not from group 1 but group(0), which is the whole string. try this:
ac.name = m.Groups[1].Value;
ac.number = m.Groups[2].Value;
This regex is correct. I think your mistake is in somewhere else. You seem to use C#. So, you should think about the regex usage in the language.
Looking to the code sample in MSDN, you need to use 1-based indexes while accessing Groups instead of zero-based (as also Kent suggested). So, use this:
String name = m.Groups[1].Value;
String number = m.Groups[2].Value;
use this regex (\w+)#(\d+([.,]\d+)?)
Groups[1] will be contain name
Groups[2] will be contain number
I think you should move the + into the capture group:
#"^([a-zA-Z._]+)#([\d]+)"
If this is C#, try without the ^
([a-zA-Z\._]+)#([\d]+)
I just tried it out and it groups properly
Update: escaped the .
If you want only one match (and hence the ^ in original expression), use .Match instead of .Matches method. See MSDN documentation on Regular Expression Classes.

C# string masking/formatting/filtering with or without regex

Hopefully this isn't too complicated, I just can't seem to find the answer I need.
I have a string with variables in, such as: this is a %variable% string
The format of the variables within the string is arbitrary, although in this example we're using the filter %{0}%
I am wanting to match variable names to properties and ideally I don't want to loop through GetProperties, formatting and testing each name. What I'd like to do is obtain "variable" as a string and test that.
I already use RegEx to get a list of the variables in a string, using the given filter:
string regExSyntax = string.Format(syntax, #"(?<word>\w+)");
but this returns them WITH the '%' (e.g. '%variable%') and as I said, that filter is arbitrary so I can't just do a string.Replace.
This feels like it should be straight-forward....
Thanks!
"(?<word>\w+)"
Is just capturing anything alphnumeric and putting it into a named capturing group called "Word"
You might be interested in learning about lookbehind and lookahead. For example:
"(?<=%)(?<word>\w+)(?=%)"
You can make it a bit more generic with putting your filter in a seperate variable:
string Boundie = "%";
string Expression = #"(?<=" + Boundie + #")(?<word>\w+)(?=" + Boundie + #")";
I hope this is anywhere near what you are looking for.
Given that your regex syntax is: string regExSyntax = string.Format(syntax, #"(?<word>\w+)");, I assume you're then going to create a Regex and use it to match against some string:
Regex reExtractVars = new Regex(regExSyntax);
Match m = reExtractVars.Match(inputString);
while (m.Success)
{
// get the matched variable
string wholeVar = m.Value; // returns "%variable%"
// get just the "word"
string wordOnly = m.Groups["word"].Value; // returns "variable"
m = m.NextMatch();
}
Or have I completely misunderstood the problem?
Acron,
If you're going to roll-your own script parser... apart from being "a bit mad", unless that's the point of the exercise (is it?), then I strongly suggest that you KISS it... Keep It Simple Stoopid.
So what denotes a VARIABLE in your scripting syntax? Is it the percent signs? And they're fixed, yes? So %name% is a variable, but #comment# is NOT a variable... correct? The phrase "that filter is arbitrary" has me worried. What's a "filter"?
If this isn't homework then just use an existing scripting engine, with existing, well defined, well known syntax. Something like Jint, for example.
Cheers. Keith.

c# regex - matching optionals after a named group

I'm sure this has been quite numerous times but though i've checked all similar questions, i couldn't come up with a solution.
The problem is that i've an input urls similar to;
http://www.justin.tv/peacefuljay
http://www.justin.tv/peacefuljay#/w/778713616/3
http://de.justin.tv/peacefuljay#/w/778713616/3
I want to match the slug part of it (in above examples, it's peacefuljay).
Regex i've tried so far are;
http://.*\.justin\.tv/(?<Slug>.*)(?:#.)?
http://.*\.justin\.tv/(?<Slug>.*)(?:#.)
But i can't come with a solution. Either it fails in the first url or in others.
Help appreciated.
The easiest way of parsing a Uri is by using the Uri class:
string justin = "http://www.justin.tv/peacefuljay#/w/778713616/3";
Uri uri = new Uri(justin);
string s1 = uri.LocalPath; // "/peacefuljay"
string s2 = uri.Segments[1]; // "peacefuljay"
If you insisnt on a regex, you can try someting a bit more specific:
Match mate = Regex.Match(str, #"http://(\w+\.)*justin\.tv(?:/(?<Slug>[^#]*))?");
(\w+\.)* - Ensures you match the domain, not anywhere else in the string (eg, hash or query string).
(?:/(?<Slug>[^#]*))? - Optional group with the string you need. [^#] limits the characters you expect to see in your slug, so it should eliminate the need of the extra group after it.
As I see it there's no reason to treat to the parts after the "slug".
Therefore you only need to match all characters after the host that aren't "/" or "#".
http://.*\.justin\.tv/(?<Slug>[^/#]+)
http://.*\.justin\.tv/(?<Slug>.*)#*?
or
http://.*\.justin\.tv/(?<Slug>.*)(#|$)

How to Extract the Word Following a Symbol?

I have a string that could have any sentence in it but somewhere in that string will be the # symbol, followed by an attached word, sort of like #username you see on some sites.
so maybe the string is "hey how are you" or it's "#john hey how are you".
IF there's an "#" in the string i want to pull what comes immediately after it into its own new string.
in this instance how can i pull "john" into a different string so i could theoretically notify this person of his new message? i'm trying to play with string.contains or .replace but i'm pretty new and having a hard time.
this btw is in c# asp.net
You can use the Substring and IndexOf methods together to achieve this.
I hope this helps.
Thanks,
Damian
Here's how you do it without regex:
string s = "hi there #john how are you";
string getTag(string s)
{
int atSign = s.IndexOf("#");
if (atSign == -1) return "";
// start at #, stop at sentence or phrase end
// I'm assuming this is English, of course
// so we leave in ' and -
int wordEnd = s.IndexOfAny(" .,;:!?", atSign);
if (wordEnd > -1)
return s.Substring(atSign, wordEnd - atSign);
else
return s.Substring(atSign);
}
You should really learn regular expressions. This will work for you:
using System.Text.RegularExpressions;
var res = Regex.Match("hey #john how are you", #"#(\S+)");
if (res.Success)
{
//john
var name = res.Groups[1].Value;
}
Finds the first occurrence. If you want to find all you can use Regex.Matches. \S means anything else than a whitespace. This means it also make hey #john, how are you => john, and #john123 => john123 which may be wrong. Maybe [a-zA-Z] or similar would suit you better (depends on which characters the usernames is made of). If you would give more examples, I could tune it :)
I can recommend this page:
http://www.regular-expressions.info/
and this tool where you can test your statements:
http://regexlib.com/RESilverlight.aspx
The best way to solve this is using Regular Expressions. You can find a great resource here.
Using RegEx, you can search for the pattern you are after. I always have to refer to some documentation to write one...
Here is a pattern to start with - "#(\w+)" - the # will get matched, and then the parentheses will indicate that you want what comes after. The "\w" means you want only word characters to match (a-z or A-Z), and the "+" indicates that there should be one or more word characters in a row.
You can try Regex...
I think will be something like this
string userName = Regex.Match(yourString, "#(.+)\\s").Groups[1].Value;
RegularExpressions. Dont know C#, but the RegEx would be
/(#[\w]+) / - Everything in the parans is captured in a special variable, or attached to RegEx object.
Use this:
var r = new Regex(#"#\w+");
foreach (Match m in r.Matches(stringToSearch))
DoSomething(m.Value);
DoSomething(string foundName) is a function that handles name (found after #).
This will find all #names in stringToSearch

Categories

Resources