i am currenty having a problem related with regex.replace . I have an item in checkedlistbox that contains a string with parenthesis "()" :
regx2[4] = new Regex( "->" + checkedListBox1.SelectedItem.ToString());
the example setence inside the selected item is
hello how are you (today)
i use it in regex like this :
if (e.NewValue == CheckState.Checked)
{
//replaces the string without parenthesis with the one with parenthesis
//ex:<reason1> ----> hello, how are you (today) (worked fine)
richTextBox1.Text = regx2[selected].Replace(richTextBox1.Text,"->"+checkedListBox1.Items[selected].ToString());
}
else if (e.NewValue == CheckState.Unchecked)
{
//replaces the string with parenthesis with the one without parenthesis
//hello, how are you (today)----><reason1> (problem)
richTextBox1.Text = regx2[4].Replace(richTextBox1.Text, "<reason" + (selected + 1).ToString() + ">");
}
it is able to replace the string on the first condition but unable to re-replace the setences again on second because it has parenthesis "()", do you know how to solve this problem??
thx for the response :)
Instead of:
regx2[4] = new Regex( "->" + checkedListBox1.SelectedItem.ToString());
Try:
regx2[4] = new Regex(Regex.Escape("->" + checkedListBox1.SelectedItem));
To use any of the special characters as a literal in a regex, you need to escape them with a backslash. If you want to match 1+1=2, the correct regex is 1\+1=2. Otherwise, the plus sign has a special meaning.
http://www.regular-expressions.info/characters.html
special characters:
backslash \,
caret ^,
dollar sign $,
period or dot .,
vertical bar or pipe symbol |,
question mark ?,
asterisk or star *,
plus sign +,
opening parenthesis (,
closing parenthesis ),
opening square bracket [,
opening curly brace {
To fix it you could probably do this:
regx2[4] = new Regex("->" + checkedListBox1.SelectedItem.ToString().Replace("(", #"\(").Replace(")", #"\)"));
But I would just use string.replace() since you aren't doing any parsing. I can't tell what you're transforming from/to and why you use selected as an index on the regex array in the if and 4 as the index in the else.
Related
I'm facing an issue with removing escape sequence from string using C#
var street = "1324 W. 650 N.\t";
Above I mentioned my code please check once and mention below comments on how to remove escape sequences like "\t".
If you only want to remove '\t' try:
var street = "1324 W. 650 N.\t";
var removed = street.Replace("\t", "");
In case you would also like to remove '\n' and '\r' too, you can concatenate the operation 'Replace()'.
var street = "1324 W. 650 N.\t";
var removed = street.Replace("\t", "").Replace("\n", "").Replace("\r", "");
Check the example I made.
You'll want to use Regex.Unescape method.
String unescapedString = Regex.Unescape(textString);
However, becareful that the Regex.Unescape doesn't un-escape ". According to the documentation, it does the following:
..by removing the escape character ("") from each character escaped by the method. These include the , *, +, ?, |, {, [, (,), ^, $,., #, and white space characters. In addition, the Unescape method unescapes the closing bracket (]) and closing brace (}) characters.
I have a question that has asked before in this link, but there is no right answer in the link. I have some sql query text and I want to get all function's names (the whole name, contain schema) that has created in these.
my string may be like this:
create function [SN].[FunctionName] test1 test1 ...
create function SN.FunctionName test2 test2 ...
create function functionName test3 test3 ...
and I want to get both [SN].[FunctionName] and SN.FunctionName,
I tried this regex :
create function (.*?\]\.\[.*?\])
but this returns only the first statement, how can I make those brackets optional in the regex expression?
This one works for me:
create function\s+\[?\w+\]?\.\[?\w+\]?
val regExp = "create function" + //required string literal
"\s+" + //allow to have several spaces before the function name
"\[?" + // '[' is special character, so we quote it and make it optional using - '?'
"\w+" + // only letters or digits for the function name
"\]?" + // optional close bracket
"\." + // require to have point, quote it with '\' because it is a special character
"\[?" + //the same as before for the second function name
"\w+" +
"\]?"
See test example: http://regexr.com/3bo0e
You can use lookarounds:
(?<=create function )(\s*\S+\..*?)(?=\s)
Demo on regex101.com
It captures everything between create function literal followed by one or more spaces and another space assuming the matched string contains at least one dot char.
To make some subpattern optional, you need to use the ? quantifier that matches 1 or 0 occurrences of the preceding subpattern.
In your case, you can use
create[ ]function[ ](?<name>\[?[^\]\s.]*\]?\.\[?[^\]\s.]*\]?)
^ ^ ^ ^
The regex matches a string starting with create function and then matching:
var rx = new Regex(#"create[ ]function[ ]
(?<name>\[? # optional opening square bracket
[^\]\s.]* # 0 or more characters other than `.`, whitespace, or `]`
\]? # optional closing square bracket
\. # a literal `.`
\[? # optional opening square bracket
[^\]\s.]* # 0 or more characters other than `.`, whitespace, or `]`
\]? # optional closing square bracket
)", RegexOptions.IgnorePatternWhitespace);
See demo
Words placed after these punctuation marks must be capitalized (note that there may be spaces or special characters on either side of these when used):
dash ( - ), slash ( / ), colon ( : ), period ( . ), question mark ( ? ), exclamation
point ( ! ), ellipsis (... OR …) (they are different)
I am sort of bogged down on this puzzle because of all of the special regex characters that I am trying to literally look for in my search. I believe I can use Regex.Escape although I cannot get it working for me right now in this case.
A few examples of starting strings to change to might be:
Change this:
This is a dash - example
To this:
This is a dash - Example <--capitalize "Example" with Regex
This is another dash -example
This is another dash -Example
This is an ellipsis ... example
This is an ellipsis ... Example
This is another ellipsis …example
This is another ellipsis …Example
This is a slash / example
This is a slash / Example
This is a question mark ? example
This is a question mark ? Example
Here is the code I have so far:
private static string[] postCaps = { "-", "/", ":", "?", "!", "...", "…"};
private static string ReplacePostCaps(string strString)
{
foreach (string postCap in postCaps)
{
strString = Regex.Replace(strString, Regex.Escape(postCap), "/(?<=(" + Regex.Escape(postCap) + "))./", RegexOptions.IgnoreCase);
}
return strString;
}
Thank you very much!
You shouldn't need to iterate over a list of punctuation but instead could just add a character set in a single regex:
(?:[/:?!…-]|\.\.\.)\s*([a-z])
To use it with Regex.Replace():
strString = Regex.Replace(
strString,
#"(?:[/:?!…-]|\.\.\.)\s*([a-z])",
m => m.ToString().ToUpper()
);
Regex Explained:
(?: # non-capture set
[/:?!…-] # match any of these characters
| \.\.\. # *or* match three `.` characters in a row
)
\s* # allow any whitespace between matched character and letter
([a-z]) # match, and capture, a single lowercase character
Maybe this works for you:
var phrase = "This is another dash ... example";
var rx = new System.Text.RegularExpressions.Regex(#"(?<=[\-./:?!]) *\w");
var newString = rx.Replace(phrase, new System.Text.RegularExpressions.MatchEvaluator(m => m.Value.ToUpperInvariant()));
I have written a utility which opens a text based file, loads is as a string and performs a find / replace function using RegEx.Replace.
It does this on many files, the user points it at a folder, enters a find string, a replace string and all the files in the folder which contain the string in the file get replaced.
This works great until I try it with a backslash where it falls down.
Quite simply:
newFileContent = Regex.Replace(fileContent, #findString, #replaceString, RegexOptions.IgnoreCase);
fileContent = the contents of a text based file. it will contain carriage returns.
findString = user entered string to find
replaceString = user entered string to replace the found string with
I've tried adding some logic to counter act the backslash as below, but this fails with illegal at end of pattern.
if (culture.CompareInfo.IndexOf(findString, #"\") >= 0)
{
Regex.Replace(findString, #"\", #"\\");
}
What do I need to do to successfully handle backslashes so they can be part of the find / replace logic?
Entire code block below.
//open reader
using (var reader = new StreamReader(f,Encoding.Default))
{
//read file
var fileContent = reader.ReadToEnd();
Globals.AppendTextToLine(string.Format(" replacing string"));
//culture find replace
var culture = new CultureInfo("en-gb", false);
//ensure nothing has changed
if (culture.CompareInfo.IndexOf(fileContent, findString, CompareOptions.IgnoreCase) >= 0)
{
//if find or replace string contains backslahes
if (culture.CompareInfo.IndexOf(findString, #"\") >= 0)
{
Regex.Replace(findString, #"\", #"\\");
}
//perform replace in new string
if (MainWindow.Main.chkIgnoreCase.IsChecked != null && (bool) MainWindow.Main.chkIgnoreCase.IsChecked)
newFileContent = Regex.Replace(fileContent, #findString, #replaceString, RegexOptions.IgnoreCase);
else
newFileContent = Regex.Replace(fileContent, #findString, #replaceString);
result[i].Result = true;
Globals.AppendTextToLine(string.Format(" success!"));
}
else
{
Globals.AppendTextToLine(string.Format(" failure!!"));
break;
}
}
You should be using Regex.Escape when you pass the user-input into the Replace method.
Escapes a minimal set of characters (\, *, +, ?, |, {, [, (,), ^, $, .,
#, and white space) by replacing them with their escape codes. This instructs the regular expression engine to interpret these characters
literally rather than as metacharacters.
For example:
newFileContent = Regex.Replace(fileContent,
Regex.Escape(findString),
replaceString,
RegexOptions.IgnoreCase);
Your fundamental issue is that your letting your user enter an arbitrary regexp and thus, well, its interpreted as a regexp...
either you goal is just to replace literal strings, in which-case use String.Replace OR you want to allow a user to enter a regexp, in which case just accept that the user will need to \ escape their special characters.
Since \ is a regexp escape char (As well as c# one but you seem to be dealing with that with #) "\" is an illegal regexp because what are you escaping
If you Really want a rexexp to replace all \ with \\ then its:
Regex.Replace(findString, #"\\", #"\\\\"); --ie one \ after escape, two chars after escape.
But you've still got [].?* etc to worry about.
My strong advice is a checkbox, user can select if they are entering a regexp or string literal for replacement and then call String.Replace or Regex.Replace accordingly
I have a CSV file that has rows resembling this:
1, 4, 2, "PUBLIC, JOHN Q" ,ACTIVE , 1332
I am looking for a regular expression replacement that will match against these rows and spit out something resembling this:
1,4,2,"PUBLIC, JOHN Q",ACTIVE,1332
I thought this would be rather easy: I made the expression ([ \t]+,) and replaced it with ,. I made a complement expression (,[ \t]+) with a replacement of , and I thought I had achieved a good means of right-trimming and left-trimming strings.
...but then I noticed that my "PUBLIC, JOHN Q" was now "PUBLIC,JOHN Q" which isn't what I wanted. (Note the space following the comma is now gone).
What would be the appropriate expression to trim the white space before and after a comma, but leave quoted text untouched?
UPDATE
To clarify, I am using an application to handle the file. This application allows me to define multiple regular expression replacements; it does not provide a parsing capability. While this may not be the ideal mechanism for this, it would sure beat making another application for this one file.
If the engine used by your tool is the C# regular expression engine, then you can try the following expression:
(?<!,\s*"(?:[^\\"]|\\")*)\s+(?!(?:[^\\"]|\\")*"\s*,)
replace with empty string.
The guys answers assumed the quotes are balanced and used counting to determine if the space is part of a quoted value or not.
My expression looks for all spaces that are not part of a quoted value.
RegexHero Demo
Something like this might do the job:
(?<!(^[^"]*"[^"]*(("[^"]*){2})*))[\t ]*,[ \t]*
Which matches [\t ]*,[ \t]*, only when not preceded by an odd number of quotes.
Going with some CSV library or parsing the file yourself would be much more easier, and IMO should be preferable option here.
But if you really insist on a regex, you can use this one:
"\s+(?=([^\"]*\"[^\"]*\")*[^\"]*$)"
And replace it with empty string - ""
This regex matches one or more whitespaces, followed by an even number of quotes. This will of course work only if you have balanced quote.
(?x) # Ignore Whitespace
\s+ # One or more whitespace characters
(?= # Followed by
( # A group - This group captures even number of quotes
[^\"]* # Zero or more non-quote characters
\" # A quote
[^\"]* # Zero or more non-quote characters
\" # A quote
)* # Zero or more repetition of previous group
[^\"]* # Zero or more non-quote characters
$ # Till the end
) # Look-ahead end
string format(string val)
{
if (val.StartsWith("\"")) val = " " + val;
string[] vals = val.Split('\"');
for (int i = 0; i < vals.Length; i += 2) vals[i] = vals[i].Replace(" ", "").Replace("\t", "");
return string.Join("\t", vals);
}
This will work if you have properly closed quoted strings in between
Forget the regex (See Bart's comment on the question, regular expressions aren't suitable for CSV).
public static string ReduceSpaces( string input )
{
char[] a = input.ToCharArray();
int placeComma = 0, placeOther = 0;
bool inQuotes = false;
bool followedComma = true;
foreach( char c in a ) {
inQuotes ^= (c == '\"');
if (c == ' ') {
if (!followedComma)
a[placeOther++] = c;
}
else if (c == ',') {
a[placeComma++] = c;
placeOther = placeComma;
followedComma = true;
}
else {
a[placeOther++] = c;
placeComma = placeOther;
followedComma = false;
}
}
return new String(a, 0, placeComma);
}
Demo: http://ideone.com/NEKm09