RegEx matching for a filename - c#

I have no experience using regular expressions, and although I should spend some time training in them, I have a need for a simple one.
I want to find a match of P*.txt in a given string (meaning anything that starts with a P, followed by anything, and ending in ".txt".
eg:
string myString = "P671221.txt";
Regex reg = new Regex("P*.txt"); //<--- what goes here?
if (reg.IsMatch(myString)
{
Console.WriteLine("Match!"));
}
This example doesn't work because it will return a match for ".txt" or "x.txt" etc. How do I do this?

myString.StartsWith("P") && myString.EndsWith(".txt")
EDIT: Removed my regex

Updated:
string start + (p) + any characters + .txt + string end
^(?i:p).*\.txt$
A more precise alternative would be:
string start + (p) + [specific characters] + .txt + string end
( currently specified are: "a-z", "0-9", space, & underscore )
^(?i:p)(?i:[a-z0-9 _])*\.txt$
Live Demo
Original Solution
( quotes were included, as I overlooked that quotes are part of the code but not
the string )
preceding quotes + (p) + any characters + .txt + following quotes
(?<=")(?i:p).*\.txt(?=")
Image
Live Demo

P[\d]+\.txt this will work. If you have fix number of digits then you can do it like P[\d]{6}\.txt. Just replace the 6 with your desired fix number.
If the value in between the starting letter P and extension .txt can be alphanumeric use P[\w]+\.txt

string myString = "P671221.txt";
Regex reg = new Regex("P(.*?)\\.txt"); //--> if anything goes after P
if (reg.IsMatch(myString))
Console.WriteLine("Match!");

This should meet the requirements that you have presented.
c#
[Pp].*.(?:txt)+$

The best option to get files that start with P & end with .txt with regex is:
^P\w+\.txt$

Related

If string contains word replace entiree string

I have the following string:
bank_38024032jr3020893 = bank_38024032jr3020893 + (call randomFunc) + 15;" \n
I want to to find and replace the bank_38024032jr3020893 with let say bank_hello how would I go at doing that? bank_38024032jr3020893 could change and I still want to be able to change it to whatever (bank_hello in the example).
I've found some good examples with regex but cant get that to work.
So what I want to is when it finds bank_xxxOldxxxit should replace that part with bank_whateverIwant
This is what I've tried:
string input2 = "bank_4556457 = bank_4556457 + (call randomFunc) + 15; \n";
string pattern2 = #"bank_";
string replace2 = "bank_55444";
string result2 = Regex.Replace(input2, pattern2, replace2);
Console.WriteLine(result2);
I understand that I cant grab the things after the "_" with that but not sure how to edit the code to fix my issue
Test this on your console:
string input = ReadLine();
WriteLine(Regex.Replace(input,"test_(\\d|[a-zA-Z])+","NewTest123"));
ReadKey();
\d matches any number, and the '+' sign means that is matches as many occurrences possible.
You should take a look at: Regular Expression in c#

Regex to disallow all symbols that windows doesnt allow in its file/folder names

The symbols not allowed in filename or folder name in windows are \ / : * ? " < > |. I wrote a regex for it but not able to write regex to exclude " (double quotes).
Regex regex = new Regex(#"^[\\\/\:\*\?\'\<\>\|]+$");
Tried as below but it didnt work:
Regex regex = new Regex(#"^[\\\/\:\*\?\'\<\>\|"]+$");
EDIT:
I am particularly looking for code with regex itself and hence its not a duplicate.
Help is greatly appreciated. Thanks.
Instead of using Regex you could do something like this:
var invalidChars = new HashSet<char>(Path.GetInvalidFileNameChars());
var invalid = input.Any(chr => invalidChars.Contains(chr));
#Allrameest answer using Path.GetInvalidFileNameChars() is probably the one you should use.
What I wanted to address is the fact that your regex is actually wrong or very ineffective (I don't know what exectly you wanted to do).
So, using:
var regex = new Regex(#"^[\\\/\:\*\?\'\<\>\|]+$");
mean you match a string which consists ONLY of "forbidden" characters (BTW, I think single quote ' is not invalid). Is it what you want? Don't think so. What you did is:
^ start of the string
[...]+ invalid characters only (at least once)
$ end of the string
Maybe you wanted #"^[^...]+$" (hat used twice)?
Anyway, solution for your problem (with regex) is:
don't use ^ or $ just try to find any of those and bomb out quickly
in raw string (the one starting with #") you escape double quotes by doubling it.
So, the right regex is:
var regex = new Regex(#"[\\\/\:\*\?\""\<\>\|]");
if (regex.Match(filename).Success) {
throw new ArgumentException("Bad filename");
}
Just find any and bomb out.
UPDATE by #JohnLBevan
var regex = new Regex(
"[" + Regex.Escape(new string(Path.GetInvalidFileNameChars())) + "]");
if (regex.Match(filename).Success) {
throw new ArgumentException("Bad filename");
}
(Not using string.Format(...) as this Regex should be static and precompiled anyway)

Replace a part of string containing Password

Slightly similar to this question, I want to replace argv contents:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
to this:
"-help=none\n-URL=(default)\n-password=********\n-uname=Khanna\n-p=100"
I have tried very basic string find and search operations (using IndexOf, SubString etc.). I am looking for more elegant solution so as to replace this part of string:
-password=AnyPassword
to:
-password=*******
And keep other part of string intact. I am looking if String.Replace or Regex replace may help.
What I've tried (not much of error-checks):
var pwd_index = argv.IndexOf("--password=");
string converted;
if (pwd_index >= 0)
{
var leftPart = argv.Substring(0, pwd_index);
var pwdStr = argv.Substring(pwd_index);
var rightPart = pwdStr.Substring(pwdStr.IndexOf("\n") + 1);
converted = leftPart + "--password=********\n" + rightPart;
}
else
converted = argv;
Console.WriteLine(converted);
Solution
Similar to Rubens Farias' solution but a little bit more elegant:
string argv = "-help=none\n-URL=(default)\n-password=\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)[^\n]*", "$1********");
It matches password= literally, stores it in capture group $1 and the keeps matching until a \n is reached.
This yields a constant number of *'s, though. But telling how much characters a password has, might already convey too much information to hackers, anyway.
Working example: https://dotnetfiddle.net/xOFCyG
Regular expression breakdown
( // Store the following match in capture group $1.
password= // Match "password=" literally.
)
[ // Match one from a set of characters.
^ // Negate a set of characters (i.e., match anything not
// contained in the following set).
\n // The character set: consists only of the new line character.
]
* // Match the previously matched character 0 to n times.
This code replaces the password value by several "*" characters:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)([\s\S]*?\n)",
match => match.Groups[1].Value + new String('*', match.Groups[2].Value.Length - 1) + "\n");
You can also remove the new String() part and replace it by a string constant

Regex to find embedded quotes in a quotes string

Original string:
11235485|56987|0|2010|05|"This is my sample
"text""|"01J400B"|""|1|"Sample "text" number two"|""sample text number
three""|""|""|
Desired string:
11235485|56987|0|2010|05|"This is my sample
""text"""|"01J400B"|""|1|"Sample ""text"" number two"|"""sample text
number three"""|""|""|
The desired string unfortunately is a requirement that is out of my control, all nested quotes MUST be qualified with quotes (I KNOW).
Try as I might I have not been able to create the desired string from the original.
A regex match/replace seems to be the way to go, I need help. Any help is appreciated.
I'd actually split the string and evaluate each piece:
public string Escape(string input)
{
string[] pieces = input.Split('|');
for (int i = 0; i < pieces.Length; i++)
{
string piece = pieces[i];
if (piece.StartsWith("\"") && piece.EndsWith("\""))
{
pieces[i] = "\"" + piece.Trim('\"').Replace("\"", "\"\"") + "\"";
}
}
return string.Join("|", pieces);
}
This is making several assumptions about the input:
Items are delimited by pipes (|)
Items are well formed and will begin and end with quotation marks
This will also break if you have |s inside of quoted strings.
You may be able to just use the normal string.Replace() method. You know that | is what starts the column, so you can replace all " to "" and then fix the column start and end by replacing |"" to |" and ""| to "|.
It'd look like this:
var input = YOUR_ORIGINAL_STRING;
input.Replace("\"", "\"\"").Replace("|\"\"", "|\"").Replace("\"\"|", "\"|"));
It's not pretty, but it gets the job done.

C# spliting string with three pieces

Hello Everybody i asked this question few hours ago C# get username from string. split
Now i have difficult problem. Trying to get Acid Player And m249 from this string
L 02/28/2012 - 06:14:22: "Acid<1><VALVE_ID_PENDING><CT>"
killed "Player<2><VALVE_ID_PENDING><TERRORIST>" with "m249"
I tried this
int start = Data.ToString().IndexOf('"') + 1;
int end = Data.ToString().IndexOf('<');
var Killer = Data.ToString().Substring(start, end - start);
int start1 = Data.ToString().IndexOf("killed") + 1;
int end1 = Data.ToString().IndexOf('<') + 4;
var Victim = Data.ToString().Substring(start1, end1 - start1);
but its show this exception on last line
Length cannot be less than zero.
Parameter name: length
Does it possible to get Both player name and last string (m249)
Tanks
Here is a simple example of how you can do it with regex. Depending on how much the string varies, this one may work for you. I'm assuming that quotes (") are consistent as well as the text between them. You'll need to add this line at the top:
Using System.Text.RegularExpressions;
Code:
string input = "L 02/28/2012 - 06:14:22: \"Acid<1><VALVE_ID_PENDING><CT>\" killed \"Player<2><VALVE_ID_PENDING><TERRORIST>\" with \"m249\"";
Regex reg = new Regex("[^\"]+\"([^<]+)<[^\"]+\" killed \"([A-Za-z0-9]+)[^\"]+\" with \"([A-Za-z0-9]+)\"");
Match m = reg.Match(input);
if (m.Success)
{
string player1 = m.Groups[1].ToString();
string player2 = m.Groups[2].ToString();
string weapon = m.Groups[3].ToString();
}
The syntax breakdown for the regex is this:
[^\"]+
means, go till we hit a double quote (")
\"
means take the quote as the next part of the string, since the previous term brings us to it, but doesn't go past it.
([^<]+)<
The parenthesis means we are interested in the results of this part, we will seek till we hit a less than (<). since this is the first "group" we're looking to extract, it's referred to as Groups[1] in the match. Again we have the character we were searching for to consume it and continue our search.
<[^\"]+\" killed \"
This will again search, without keeping the results due to no parenthesis, till we hit the next quote mark. We then manually specify the string of (" killed ") since we're interested in what's after that.
([A-Za-z0-9]+)
This will capture any characters for our Group[2] result that are alphanumeric, upper or lowercase.
[^\"]+\"
Search and ignore the rest till we hit the next double quote
with \"
Another literal string that we're using as a marker
([A-Za-z0-9]+)
Same as above, return alphanumeric as our Group[3] with the parenthesis
\"
End it off with the last quote.
Hopefully this explains it. A google for "Regular Expressions Cheat Sheet" is very useful for remembering these rules.
Should be super easy to parse. I recognized that it was CS. Take a look at Valve's documentation here:
https://developer.valvesoftware.com/wiki/HL_Log_Standard#057._Kills
Update:
If you're not comfortable with regular expressions, this implementation will do what you want as well and is along the lines of what you attempted to do:
public void Parse(string killLog)
{
string[] parts = killLog.Split(new[] { " killed ", " with " }, StringSplitOptions.None);
string player1 = parts[0].Substring(1, parts[0].IndexOf('<') - 1);
string player2 = parts[1].Substring(1, parts[1].IndexOf('<') - 1);
string weapon = parts[2].Replace("\"", "");
}
Personally, I would use a RegEx.

Categories