Is there some build in method that add quotes around string in c# ?
Do you mean just adding quotes? Like this?
text = "\"" + text + "\"";
? I don't know of a built-in method to do that, but it would be easy to write one if you wanted to:
public static string SurroundWithDoubleQuotes(this string text)
{
return SurroundWith(text, "\"");
}
public static string SurroundWith(this string text, string ends)
{
return ends + text + ends;
}
That way it's a little more general:
text = text.SurroundWithDoubleQuotes();
or
text = text.SurroundWith("'"); // For single quotes
I can't say I've needed to do this often enough to make it worth having a method though...
string quotedString = string.Format("\"{0}\"", originalString);
Yes, using concatenation and escaped characters
myString = "\"" + myString + "\"";
Maybe an extension method
public static string Quoted(this string str)
{
return "\"" + str + "\"";
}
Usage:
var s = "Hello World"
Console.WriteLine(s.Quoted())
No but you can write your own or create an extension method
string AddQuotes(string str)
{
return string.Format("\"{0}\"", str);
}
Using Escape Characters
Just prefix the special character with a backslash, which is known as an escape character.
Simple Examples
string MyString = "Hello";
Response.Write(MyString);
This would print:
Hello
But:
string MyString = "The man said \"Hello\"";
Response.Write(MyString);
Would print:
The man said "Hello"
Alternative
You can use the useful # operator to help escape strings, see this link:
http://www.kowitz.net/archive/2007/03/06/the-c-string-literal
Then, for quotes, you would use double quotes to represent a single quote. For example:
string MyString = #"The man said ""Hello"" and went on his way";
Response.Write(MyString);
Outputs:
The man said "Hello" and went on his way
I'm a bit C# of a novice myself, so have at me, but I have this in a catch-all utility class 'cause I miss Perl:
// overloaded quote - if no quote chars spec'd, use ""
public static string quote(string s) {
return quote(s, "\"\"");
}
// quote a string
// q = two quote chars, like "", '', [], (), {} ...
// or another quoted string (quote-me-like-that)
public static string quote(string s, string q) {
if(q.Length == 0) // no quote chars, use ""
q = "\"\"";
else if(q.Length == 1) // one quote char, double it - your mileage may vary
q = q + q;
else if(q.Length > 2) // longer string == quote-me-like-that
q = q.Substring(0, 1) + q.Substring(q.Length - 1, 1);
if(s.Length == 0) // nothing to quote, return empty quotes
return q;
return q[0] + s + q[1];
}
Use it like this:
quote("this with default");
quote("not recommended to use one char", "/");
quote("in square brackets", "[]");
quote("quote me like that", "{like this?}");
Returns:
"this with default"
/not recommended to use one char/
[in square brackets]
{quote me like that}
In my case I wanted to add quotes only if the string was not already surrounded in quotes, so I did:
(this is slightly different to what I actually did, so it's untested)
public static string SurroundWith(this string text, string ends)
{
if (!(text.StartsWith(ends) && text.EndsWith(ends)))
{
return string.Format("{1}{0}{1}", text, ends);
}
else
{
return text;
}
}
There is no such built in method to do your requirement
There is SplitQuotes method that does something
Input - This is a "very long" string
Output - This, is, a, very long, string
When you get a string from textbox or some control it comes with quotes.
If still you want to place quotes then you can use this kind of method
private string PlaceQuotes(string str, int startPosition, int lastPosition)
{
string quotedString = string.Empty;
string replacedString = str.Replace(str.Substring(0, startPosition),str.Substring(0, startPosition).Insert(startPosition, "'")).Substring(0, lastPosition).Insert(lastPosition, "'");
return String.Concat(replacedString, str.Remove(0, replacedString.Length));
}
Modern C# version below. Using string.Create() we avoid unnecessary allocations:
public static class StringExtensions
{
public static string Quote(this string s) => Surround(s, '"');
public static string Surround(this string s, char c)
{
return string.Create(s.Length + 2, s, (chars, state) =>
{
chars[0] = c;
state.CopyTo(chars.Slice(1));
chars[^1] = c;
});
}
}
Related
I'm having issues doing a find / replace type of action in my function, i'm extracting the < a href="link">anchor from an article and replacing it with this format: [link anchor] the link and anchor will be dynamic so i can't hard code the values, what i have so far is:
public static string GetAndFixAnchor(string articleBody, string articleWikiCheck) {
string theString = string.Empty;
switch (articleWikiCheck) {
case "id|wpTextbox1":
StringBuilder newHtml = new StringBuilder(articleBody);
Regex r = new Regex(#"\<a href=\""([^\""]+)\"">([^<]+)");
string final = string.Empty;
foreach (var match in r.Matches(theString).Cast<Match>().OrderByDescending(m => m.Index))
{
string text = match.Groups[2].Value;
string newHref = "[" + match.Groups[1].Index + " " + match.Groups[1].Index + "]";
newHtml.Remove(match.Groups[1].Index, match.Groups[1].Length);
newHtml.Insert(match.Groups[1].Index, newHref);
}
theString = newHtml.ToString();
break;
default:
theString = articleBody;
break;
}
Helpers.ReturnMessage(theString);
return theString;
}
Currently, it just returns the article as it originally is, with the traditional anchor text format: < a href="link">anchor
Can anyone see what i have done wrong?
regards
If your input is HTML, you should consider using a corresponding parser, HtmlAgilityPack being really helpful.
As for the current code, it looks too verbose. You may use a single Regex.Replace to perform the search and replace in one pass:
public static string GetAndFixAnchor(string articleBody, string articleWikiCheck) {
if (articleWikiCheck == "id|wpTextbox1")
{
return Regex.Replace(articleBody, #"<a\s+href=""([^""]+)"">([^<]+)", "[$1 $2]");
}
else
{
// Helpers.ReturnMessage(articleBody); // Uncomment if it is necessary
return articleBody;
}
}
See the regex demo.
The <a\s+href="([^"]+)">([^<]+) regex matches <a, 1 or more whitespaces, href=", then captures into Group 1 any one or more chars other than ", then matches "> and then captures into Group 2 any one or more chars other than <.
The [$1 $2] replacement replaces the matched text with [, Group 1 contents, space, Group 2 contents and a ].
Updated (Corrected regex to support whitespaces and new lines)
You can try this expression
Regex r = new Regex(#"<[\s\n]*a[\s\n]*(([^\s]+\s*[ ]*=*[ ]*[\s|\n*]*('|"").*\3)[\s\n]*)*href[ ]*=[ ]*('|"")(?<link>.*)\4[.\n]*>(?<anchor>[\s\S]*?)[\s\n]*<\/[\s\n]*a>");
It will match your anchors, even if they are splitted into multiple lines. The reason why it is so long is because it supports empty whitespaces between the tags and their values, and C# does not supports subroutines, so this part [\s\n]* has to be repeated multiple times.
You can see a working sample at dotnetfiddle
You can use it in your example like this.
public static string GetAndFixAnchor(string articleBody, string articleWikiCheck) {
if (articleWikiCheck == "id|wpTextbox1")
{
return Regex.Replace(articleBody,
#"<[\s\n]*a[\s\n]*(([^\s]+\s*[ ]*=*[ ]*[\s|\n*]*('|"").*\3)[\s\n]*)*href[ ]*=[ ]*('|"")(?<link>.*)\4[.\n]*>(?<anchor>[\s\S]*?)[\s\n]*<\/[\s\n]*a>",
"[${link} ${anchor}]");
}
else
{
return articleBody;
}
}
I want to replace all the word that start via # with another word, here is my code:
public string SemiFinalText { get; set; }
public string FinalText { get; set; }
//sample text : "aaaa bbbb #cccc dddd #eee fff g"
public string GetProperText(string text)
{
if (text.Contains('#'))
{
int index = text.IndexOf('#');
string restText = text.Substring(index);
var indexLast = restText.IndexOf(' ');
var oldName = text.Substring(index, indexLast);
string restText2 = text.Substring( index + indexLast);
SemiFinalText += text.Substring(0, index + indexLast).Replace(oldName, "#New");
if (restText2.Contains('#'))
{
GetProperText(restText2);
}
FinalText = SemiFinalText + restText2;
return FinalText;
}
else
{
return text;
}
}
When return FinalText; is executed I want to stop recursive function. How can fix it?
Maybe another approach is better than recursive function. If you know another way please give an answer to me.
You don't need a recursive solution for this problem. You have a string containing a number of words (separated by spaces) and you want to replace the ones starting with an '#' with another string. Modifying your solution to have a simple method that splits based on spaces, replaces all words starting with # and then combines them once again.
Using Linq:
string text = "aaaa bbbb #cccc dddd #eee fff g";
FinalText = GetProperText(text, "New");
public string GetProperText(string text, string replacewith)
{
text = string.Join(" ", text.Split(' ').Select(x => x.StartsWith("#") ? replacewith: x));
return text;
}
Output: aaaa bbbb New dddd New fff g
Using Regex:
Regex rgx = new Regex("#([^ #])*");
string result = rgx.Replace(text, replaceword);
Solution with Regular Expressions:
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string pattern = #"#\w+";
var r = new Regex(pattern);
Console.WriteLine(r.Replace("ABC #ABC ABC #DEF klm.#bhsh", "BOOM!"));
}
}
This does not rely on space character being the delimiter, any non-word (letters and numbers) can be used to separate the 'words'. This example outputs:
ABC BOOM! ABC BOOM! klm.BOOM!
You can test it out here: https://dotnetfiddle.net/rZyjjg
If you're new to Regex: .NET Introduction to Regular Expressions
Here also the proper way to do it recursively for anyone interested. I think your stopping condition was actually oke, but you should concatenate the outcome of the recursive function call to the already processed text. Also I think that using global variables in a recursive function defeats its purpose a little bit.
That being said I think that using RegEx from one of the supplied answer is better and faster.
The recursive code:
//sample text : "aaaa bbbb #cccc dddd #eee fff g"
public string GetProperText(string text)
{
if (text.Contains('#'))
{
int index = text.IndexOf('#'); //Index of first occuring '#'
var indexLast = text.IndexOf(' ',index); //Index of first ' ' after '#'
var oldName = text.Substring(index, indexLast); //Old Name
string processedText = text.Substring(0, index + indexLast).Replace(oldName, "New"); //String with new name
string restText = text.Substring(indexLast); //Rest Text
if (text.Contains('#'))
{
//Here the outcome of the function is pasted on the allready processed text part.
text = processedText + GetProperText(restText);
}
return text;
}
else
{
return text;
}
}
I have been trying real hard understanding regular expression, Is there any way I can replace character(s) that is between two regex/ For example I have
string datax = "a4726e1e-babb-4898-a5d5-e29d2bc40028;POPULATE DATA AØ99c1d133-15f5-4ef5-bc59- d9ed673b70c6;POPULATE DATA BØ";
how to remove string between regex ";" and "Ø" ???
i try to use code like this :
string xresult = Regex.Replace(datax, #"(?<=;)(\w+?)(?=Ø)", "");
But not working.
please corrected and give me solutions...
thanks...
i want the result like this sir :
string datax = "a4726e1e-babb-4898-a5d5-e29d2bc40028;Ø99c1d133-15f5-4ef5-bc59-d9ed673b70c6;Ø";
I think you need to understand regex a little better and how the replace function works. with regex you're defining capture groups, and with the replace function you want to replace those groups.
how to remove string between regex ";" and "Ø" ???
Step 1: First find ";",then capture all characters up to and including "Ø".
That's (;.*?Ø)
( New Capture Group
; Match ";"
. Match Anything
* Zero or more times
? Be Lazy
Ø Match "Ø"
) End Capture
Step 2: Replace each group with ";Ø"
public static string Replace(string input, string pattern, string
replacement)
So you need to put back the ";Ø" you removed from the original capture.
static void Test2()
{
foreach (string item in SO2588078())
{
Console.WriteLine(item);
}
string input = "a4726e1e-babb-4898-a5d5-e29d2bc40028;POPULATE DATA AØ99c1d133-15f5-4ef5-bc59- d9ed673b70c6;POPULATE DATA BØ";
string regex = "(;.*?Ø)";
string output = Regex.Replace(input, regex, ";Ø");
if (output == string.Join(";Ø", SO2588078()) + ";Ø")
{
Console.WriteLine("TRUE");
}
}
An alternative would be to parse the string without regex. It's a simple format and this gives you more control over the process so you can see what's happening, why it's gone wrong and why it gives the results it does. Since you can step through it.
private static IEnumerable<string> SO2588078()
{
string datax = "a4726e1e-babb-4898-a5d5-e29d2bc40028;POPULATE DATA AØ99c1d133-15f5-4ef5-bc59- d9ed673b70c6;POPULATE DATA BØ";
string temp = datax;
while (!string.IsNullOrEmpty(temp))
{
int index1 = temp.IndexOf(';');
if (index1 > -1)
{
string guid = temp.Remove(index1);
yield return guid;
int index2 = temp.IndexOf('Ø');
if (index2 > -1)
{
temp = temp.Substring(index2 + 1);
}
else
{
temp = null;
}
}
else
{
temp = null;
}
}
}
I want to get the page name from a URI for instance if I have
"/Pages/Alarm/AlarmClockPage.xaml"
I want to get AlarmClockPage
I tried
//usage GetSubstring("/", ".", "/Pages/Alarm/AlarmClockPage.xaml")
public static string GetSubstring(string a, string b, string c)
{
string str = c.Substring((c.IndexOf(a) + a.Length),
(c.IndexOf(b) - c.IndexOf(a) - a.Length));
return str;
}
But because the string being search may contain one or more forward slashes, I don't think this method work in such case.
So how do I consider the multiple forward slashes that may present?
Why don't you use method which is already in the framework?
System.IO.Path.GetFileNameWithoutExtension(#"/Pages/Alarm/AlarmClockPage.xaml");
If you only want to use string functions, you may try:
var startIdx = pathString.LastIndexOf(#"/");
var endIdx = pathString.LastIndexOf(".");
if(endIdx!=-1)
{
fileName = pathString.Substring(startIdx,endIdx);
}
else
{
fileName = pathString.Substring(startIdx);
}
It gives file name from a given file path. try this
string pageName = System.IO.Path.GetFileName(#"/Pages/Alarm/AlarmClockPage.xaml");
This is not about encoding URLs its more to do with a problem I noticed where you can have a valid filename on IIS sucha as "test & test.jpg" but this cannot be downloaded due to the & causing an error. There are other characters that do this also that are valid in windows but not for web.
My quick solution is to change the filename before saving using a regex below...
public static string MakeFileNameWebSafe(string fileNameIn)
{
string pattern = #"[^A-Za-z0-9. ]";
string safeFilename = System.Text.RegularExpressions.Regex.Replace(fileNameIn, pattern, string.Empty);
if (safeFilename.StartsWith(".")) safeFilename = "noname" + safeFilename;
return safeFilename;
}
but I was wondering if there were any better built in ways of doing this.
Built-in I don't know about.
What you can do is, like you say, scan the original filename and generate a Web-safe version of it.
For such Web-safe versions, you can make it appear like slugs in blogs and blog categories (these are search engine-optimized):
Only lowercase characters
Numbers are allowed
Dashes are allowed
Spaces are replaced by dashes
Nothing else is allowed
Possibly you could replace "&" by "-and-"
So "test & test.jpg" would translate to "test-and-test.jpg".
Just looking back at this question since its fairly popular. Just though I would post my current solution up here with various overloads for anyone who wants it..
public static string MakeSafeFilename(string filename, string spaceReplace)
{
return MakeSafeFilename(filename, spaceReplace, false, false);
}
public static string MakeSafeUrlSegment(string text)
{
return MakeSafeUrlSegment(text, "-");
}
public static string MakeSafeUrlSegment(string text, string spaceReplace)
{
return MakeSafeFilename(text, spaceReplace, false, true);
}
public static string MakeSafeFilename(string filename, string spaceReplace, bool htmlDecode, bool forUrlSegment)
{
if (htmlDecode)
filename = HttpUtility.HtmlDecode(filename);
string pattern = forUrlSegment ? #"[^A-Za-z0-9_\- ]" : #"[^A-Za-z0-9._\- ]";
string safeFilename = Regex.Replace(filename, pattern, string.Empty);
safeFilename = safeFilename.Replace(" ", spaceReplace);
return safeFilename;
}
I think you are referring to the "A potentially dangerous Request.Path value was detected from the client (%)" error which Asp.Net throws for paths which include characters which might indicate cross site scripting attempts:
there is a good article on how to work around this:
http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx
Here's the one I use:
public static string MakeFileNameWebSafe(string path, string replace, string other)
{
var folder = System.IO.Path.GetDirectoryName(path);
var name = System.IO.Path.GetFileNameWithoutExtension(path);
var ext = System.IO.Path.GetExtension(path);
if (name == null) return path;
var allowed = #"a-zA-Z0-9" + replace + (other ?? string.Empty);
name = System.Text.RegularExpressions.Regex.Replace(name.Trim(), #"[^" + allowed + "]", replace);
name = System.Text.RegularExpressions.Regex.Replace(name, #"[" + replace + "]+", replace);
if (name.EndsWith(replace)) name = name.Substring(0, name.Length - 1);
return folder + name + ext;
}
If you are not concerned to keep the original name perhaps you could just replace the name with a guid?