I want to use regex to get a filename without extension. I'm having trouble getting regex to return a value. I have this:
string path = #"C:\PERSONAL\TEST\TESTFILE.PDF";
var name = Regex.Match(path, #"(.+?)(\.[^\.]+$|$)").Value;
In this case, name always comes back as C:\PERSONAL\TEST\TESTFILE.PDF. What am I doing wrong, I think my search pattern is correct?
(I am aware that I could use Path.GetFileNameWithoutExtension(path);but I specifically want to try using regex)
You need Group[1].Value
string path = #"C:\PERSONAL\TEST\TESTFILE.PDF";
var match = Regex.Match(path, #"(.+?)(\.[^\.]+$|$)");
if(match.Success)
{
var name = match.Groups[1].Value;
}
match.Value returns the Captures.Value which is the entire match
match.Group[0] always has the same value as match.Value
match.Group[1] return the first capture value
For example:
string path = #"C:\PERSONAL\TEST\TESTFILE.PDF";
var match = Regex.Match(path, #"(.+?)(\.[^\.]+$|$)");
if(match.Success)
{
Console.WriteLine(match.Value);
// return the substring of the matching part
//Output: C:\\PERSONAL\\TEST\\TESTFILE.PDF
Console.WriteLine(match.Groups[0].Value)
// always the same as match.Value
//Output: C:\\PERSONAL\\TEST\\TESTFILE.PDF
Console.WriteLine(match.Groups[1].Value)
// return the first capture group which is (.+?) in this case
//Output: C:\\PERSONAL\\TEST\\TESTFILE
Console.WriteLine(match.Groups[2].Value)
// return the second capture group which is (\.[^\.]+$|$) in this case
//Output: .PDF
}
Since the data is on the right side of the string, tell the regex parser to work from the end of the string to the beginning by using the option RightToLeft. Which will significantly reduce the processing time as well as lessen the actual pattern needed.
The pattern below reads from left to right and says, give me everything that is not a \ character (to consume/match up to the slash and not proceed farther) and start consuming up to a period.
Regex.Match(#"C:\PERSONAL\TEST\TESTFILE.PDF",
#"([^\\]+)\.",
RegexOptions.RightToLeft)
.Groups[1].Value
Prints out
TESTFILE
Try this:
.*(?=[.][^OS_FORBIDDEN_CHARACTERS]+$)
For Windows:
OS_FORBIDDEN_CHARACTERS = :\/\\\?"><\|
this is a sleight modification of:
Regular expression get filename without extention from full filepath
If you are fine to match forbidden characters then simplest regex would be:
.*(?=[.].*$)
Can be a bit shorter and greedier:
var name = Regex.Replace(#"C:\PERS.ONAL\TEST\TEST.FILE.PDF", #".*\\(.*)\..*", "$1"); // "TEST.FILE"
Related
I have a string and I want to get the words after the last dot in the string.
Example:
input string = "XimEngine.DynamicGui.PickKind.DropDown";
Result:
DropDown
There's no need in Regex, let's find out the last . and get Substring:
string result = input.Substring(input.LastIndexOf('.') + 1);
If input doesn't have . the entire input will be returned
Not a RegEx answer, but you could do:
var result = input.Split('.').Last();
In Regex you can tell the parser to work from the end of the string/buffer by specifying the option RightToLeft.
By using that we can just specify a forward pattern to find a period (\.) and then capture (using ( )) our text we are interested into group 1 ((\w+)).
var str = "XimEngine.DynamicGui.PickKind.DropDown";
Console.WriteLine(Regex.Match(str,
#"\.(\w+)",
RegexOptions.RightToLeft).Groups[1].Value);
Outputs to console:
DropDown
By working from the other end of the string means we don't have to deal with anything at the beginning of the string to where we need to extract text.
Well, I have this code:
StreamReader sr = new StreamReader(#"main.cl", true);
String str = sr.ReadToEnd();
Regex r = new Regex(#"&");
string[] line = r.Split(str);
foreach (string val in line)
{
string Change = val.Replace("puts","System.Console.WriteLine()");
Console.Write(Change);
}
As you can see, I'm trying to replace puts (content) by Console.WriteLine(content) but it would be need Regular Expressions and I didn't found a good article about how to do THIS.
Basically, taking * as the value that is coming, I'd like to do this:
string Change = val.Replace("puts *","System.Console.WriteLine(*)");
Then, if I receive:
puts "Hello World";
I want to get:
System.Console.WriteLine("Hello World");
You need to use Regex.Replace to capture part of the input by using a capturing group and include the captured match into the output. Example:
Regex.Replace(
"puts 'foo'", // input
"puts (.*)", // .* means "any number of characters"
"System.Console.WriteLine($1)") // $1 stands for whatever (.*) matched
If the input always ends in a semicolon you would want to move that semicolon outside the WriteLine parens. One way to do that is:
Regex.Replace(
"puts 'foo';", // input
"puts (.*);", // ; outside parens -- now it's not captured
"System.Console.WriteLine($1);") // manually adding the fixed ; at the end
If you intend to adapt these examples it's a good idea to consult a technical reference first; you can find a very good one here.
What you want to do is look at Grouping Expressions. Give the following a try
Regex.Replace(val, "puts (.*);", "System.Console.WriteLine(${1});");
Note that you can also name your groups, as opposed to using their indexes for replacement. You can do this like so:
Regex.Replace(val, "puts (?<str>.*);", "System.Console.WriteLine(${str});");
I'm trying to figure out a pattern where I run a regex match on a long string, and each time it finds a match, it runs a replace on it. The thing is, the replace will vary depending on the matched value. This new value will be determined by a method. For example:
var matches = Regex.Match(myString, myPattern);
while(matches.Success){
Regex.Replace(myString, matches.Value, GetNewValue(matches.Groups[1]));
matches = matches.NextMatch();
}
The problem (i think) is that if I run the Regex.Replace, all of the match indexes get messed up so the result ends up coming out wrong. Any suggestions?
If you replace each pattern with a fixed string, Regex.replace does that for you. You don't need to iterate the matches:
Regex.Replace(myString, myPattern, "replacement");
Otherwise, if the replacement depends upon the matched value, use the MatchEvaluator delegate, as the 3rd argument to Regex.Replace. It receives an instance of Match and returns string. The return value is the replacement string. If you don't want to replace some matches, simply return match.Value:
string myString = "aa bb aa bb";
string myPattern = #"\w+";
string result = Regex.Replace(myString, myPattern,
match => match.Value == "aa" ? "0" : "1" );
Console.WriteLine(result);
// 0 1 0 1
If you really need to iterate the matches and replace them manually, you need to start replacement from the last match towards the first, so that the index of the string is not ruined for the upcoming matches. Here's an example:
var matches = Regex.Matches(myString, myPattern);
var matchesFromEndToStart = matches.Cast<Match>().OrderByDescending(m => m.Index);
var sb = new StringBuilder(myString);
foreach (var match in matchesFromEndToStart)
{
if (IsGood(match))
{
sb.Remove(match.Index, match.Length)
.Insert(match.Index, GetReplacementFor(match));
}
}
Console.WriteLine(sb.ToString());
Just be careful, that your matches do not contain nested instances. If so, you either need to remove matches which are inside another match, or rerun the regex pattern to generate new matches after each replacement. I still recommend the second approach, which uses the delegates.
If I understand your question correctly, you want to perform a replace based on a constant Regular Expression, but the replacement text you use will change based on the actual text that the regex matches on.
The Captures property of the Match Class (not the Match method) returns a collection of all the matches with your regex within the input string. It contains information like the position within the string, the matched value and the length of the match. If you iterate over this collection with a foreach loop you should be able to treat each match individually and perform some string manipulations where you can dynamically modify the replacement value.
I would use something like
Regex regEx = new Regex("some.*?pattern");
string input = "someBLAHpattern!";
foreach (Match match in regEx.Matches(input))
{
DoStuffWith(match.Value);
}
i have this string:
"Network adapter 'Realtek PCIe GBE Family Controller' on local host"
what will be the best way to return only the string between "'" ? (Realtek PCIe GBE Family Controller)
If you're comfortable with regular expressions, you could use a pattern like:
/'[^']*'/
to capture everything between the single quotes
You can use regular expressions, like this:
var s = "hello 'world' hehe";
var m = Regex.Match(s, "'([^']*)'");
string res = null;
if (m.Success) {
res = m.Groups[1].ToString();
}
Console.WriteLine(res);
The key to the solution is this regular expression:
'([^']*)'
It starts the match when it finds a single quote, and continues until it finds the closing quote, capturing everything in between. The captured group is then retrieved through the Regex API. Note that the capturing groups that you define start at index 1; index zero is reserved to mean "the entire match".
Take a look at the demo on ideone.
You can use the Substring() method to chop it up.
tempStr = str.Substring(str.IndexOf("'")+1);
yourStr = tempStr.SubString(0, tempStr.IndexOf("'"));
I need a regular expression to basically get the first part of a string, before the first slash ().
For example in the following:
C:\MyFolder\MyFile.zip
The part I need is "C:"
Another example:
somebucketname\MyFolder\MyFile.zip
I would need "somebucketname"
I also need a regular expression to retrieve the "right hand" part of it, so everything after the first slash (excluding the slash.)
For example
somebucketname\MyFolder\MyFile.zip
would return
MyFolder\MyFile.zip.
You don't need a regular expression (it would incur too much overhead for a simple problem like this), try this instead:
yourString = yourString.Substring(0, yourString.IndexOf('\\'));
And for finding everything after the first slash you can do this:
yourString = yourString.Substring(yourString.IndexOf('\\') + 1);
This problem can be handled quite cleanly with the .NET regular expression engine. What makes .NET regular expressions really nice is the ability to use named group captures.
Using a named group capture allows you to define a name for each part of regular expression you are interested in “capturing” that you can reference later to get at its value. The syntax for the group capture is "(?xxSome Regex Expressionxx). Remember also to include the System.Text.RegularExpressions import statement when using regular expression in your project.
Enjoy!
//Regular expression
string _regex = #"(?<first_part>[a-zA-Z:0-9]+)\\{1}(?<second_part>(.)+)";
//Example 1
{
Match match = Regex.Match(#"C:\MyFolder\MyFile.zip", _regex, RegexOptions.IgnoreCase);
string firstPart = match.Groups["first_part"].Captures[0].Value;
string secondPart = match.Groups["second_part"].Captures[0].Value;
}
//Example 2
{
Match match = Regex.Match(#"somebucketname\MyFolder\MyFile.zip", _regex, RegexOptions.IgnoreCase);
string firstPart = match.Groups["first_part"].Captures[0].Value;
string secondPart = match.Groups["second_part"].Captures[0].Value;
}
You are aware that .NET's file handling classes do this a lot more elegantly, right?
For example in your last example, you could do:
FileInfo fi = new FileInfo(#"somebucketname\MyFolder\MyFile.zip");
string nameOnly = fi.Name;
The first example you could do:
FileInfo fi = new FileInfo(#"C:\MyFolder\MyFile.zip");
string driveOnly = fi.Root.Name.Replace(#"\", "");
This matches all non \ chars
[^\\]*
Here is the regular expression solution using the "greedy" operator '?'...
var pattern = "^.*?\\\\";
var m = Regex.Match("c:\\test\\gimmick.txt", pattern);
MessageBox.Show(m.Captures[0].Value);
Split on slash, then get first item
words = s.Split('\\');
words[0]