I need to format some text entered by user.
For example: string str = "{{Lorem Ipsum|bold}}" is simply dummy text of the printing and typesetting industry.
I have extracted Lorem Ipsum from the string using IndexOf and displayed in Bold. But facing problem if I have two words to format in same string.
For example: string str ="{{Lorem Ipsum|bold}}" is simply dummy text of the "{{printing|blue}}" and typesetting industry.
Can someone help me out with any Regex pattern to extract {{Lorem Ipsum|bold}} and {{printing|blue}} as a array in c#.
Note: The pattern sometimes may be {{printing|blue,bold,http://www.google.com}}.
Extension Method for formatting. I have hard coded for testing, later i'll optimize accordingly.
public static string Format(this string value)
{
System.Uri uriResult = null;
bool result = false;
string path = ConfigurationManager.AppSettings["path"];
if (value.Length > 0)
{
if (value.Contains("{{") && value.Contains("|") && value.Contains("}}"))
{
int totalLength = value.Length;
string unformattedText = value.Substring(value.IndexOf("{{"), (value.IndexOf("}}") - value.IndexOf("{{")) + 2);
string flowersRemoved = unformattedText.Substring(0, unformattedText.Length - 2);
flowersRemoved = flowersRemoved.Substring(2, flowersRemoved.Length - 2);
string[] textFormats = flowersRemoved.Split('|');
string text = textFormats[0];
string[] formats = textFormats[1].Split(',');
foreach (string format in formats)
{
result = Uri.TryCreate(format.ToLower(), UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp;
if (format.ToLower() == "bold")
text = "<b>" + text + "</b>";
else if (format.ToLower() == "red")
text = "<font color = \"red\">" + text + "</font>";
else if (format.ToLower() == "blue")
text = "<font color = \"blue\">" + text + "</font>";
else if (result)
text = "" + text + "";
else if (System.IO.File.Exists(path + format))
{
string fileName = System.IO.Path.GetFileName(path + format);
text = "" + text + "";
}
}
value = value.Replace(unformattedText, text);
}
return value;
}
return value;
}
You can use next regexp with replace function
string str = "{{Lorem Ipsum|bold}}";
string path = ConfigurationManager.AppSettings["path"];
var formattedString = Regex.Replace(str, #"{{(?<symbol>[^|]+?)\|(?<formats>.+?)}}", m =>
{
var formatedPattern = m.Groups["formats"].Value.Split(',').Aggregate("{0}", (acc, f) =>
{
switch (f.ToLower())
{
case "bold": return "<b>" + acc + "</b>";
case "red": return "<font color = \"red\">" + acc + "</font>";
case "blue": return "<font color = \"blue\">" + acc + "</font>";
};
Uri uriResult;
if (Uri.TryCreate(f.ToLower(), UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp)
{
return "" + acc + "";
}
else if (System.IO.File.Exists(path + f))
{
string fileName = System.IO.Path.GetFileName(path + f);
return "" + acc + "";
}
return acc;
});
return string.Format(formatedPattern, m.Groups["symbol"].Value);
});
The pattern sometimes may be {{printing|blue,bold,http://www.google.com}}.
Try Split.
The following fiddle uses Split() not regex, because regex tends to be hard to read. The resultant key string contains the word to format, and a values string array contains the relevant settings.
string str = "{{printing|blue,bold,http://www.google.com}}";
// get your settings
int pFrom = str.IndexOf("{{") + "{{".Length;
int pTo = str.LastIndexOf("}}");
string settings = str.Substring(pFrom, pTo - pFrom);
// split
string[] parts = settings.Split('|');
string key = parts[0];
string[] values = parts[1].Split(',');
// for demo purposes only
Console.WriteLine(key);
foreach(var v in values)
{
Console.WriteLine("-" + v);
}
Output
printing
-blue
-bold
-http://www.google.com
If you tack this on the end you can have your desired HTML:
// create html
var html = string.Format(#"
<a href='{3}' target ='_blank'>
<font color='{1}'>
<b>{0}</b>
</font>
</a>", key, values[0], values[1], values[2]);
Console.WriteLine(html);
Output
<a href ='http://www.google.com' target = '_blank'>
<font color ='blue'>
<b>printing</b>
</font>
</a>
Watch it run here.
Related
I am trying to construct a string which I want to use it to update a JSON.
The code is below
public string ConstructCylicLoop(string fieldName, int LoopCount, string BadDataLabel,string ImmediateParent)
{
string start = "";
string fullbody = "";
string end = "";
string body = "";
for (int i = 0; i < LoopCount; i++)
{
LoopTestData = (new ExcelUtilities().getAPITestData(ApplicationConfiguration.LoopSheetName));
body = "";
foreach (Dictionary<string, string> loopData in LoopTestData)
{
string ParentNode = "";
string Key = "";
string Data = "";
loopData.TryGetValue("ParentNode", out ParentNode);
loopData.TryGetValue("Key", out Key);
loopData.TryGetValue("Data", out Data);
if(ImmediateParent.Equals(ParentNode)) //&& Key.Equals(fieldName)
{
body = body + '"' + Key + '"' + ":" + '"' + Data + '"'+',';
}
}
body = body.Remove(body.Length - 1);
body = "{" + body + "},";
fullbody = fullbody + body;
}
fullbody = fullbody.Remove(fullbody.Length - 1);
return start + fullbody + end;
}
The issue with this code is it always returns a text like this
"{\"my_address_type\":\"primarypropertyaddress\",\"my_address-street\":\"52 Street\",\"my_address-suburb\":\"vinvent\",\"my_address-postcode\":\"2121\"}"
When I update this string to an JSON node, the server is not able to parse it and the issue is with the back slash. Is there a way to remove the back slash. so I get something like this..
"{"my_address_type":"primarypropertyaddress","my_address-street":"52 Street","my_address-suburb":"vinvent","my_address-postcode":"2121"}"
I tried all possibilities but not able to clear/remove the backslash. Any code snippet on removing the backslashes. Thanks in advance.
I need to copy multiple lines from text file(cisco config file): based on the below condition
if the line starts with interface copy from interface until '! '
my file is like :
!
access-list 1>
!
interface 1
ip address xx.xx.xx.xx
!
interface 2
ip address xx.xx.xx.xx
!
route 1
!
I try the below code :
var lines = File.ReadAllLines("C:\\My File2.txt");
foreach (var line1 in lines){
string firstWord = line1.Split(' ').First();
if ((firstWord == "access-list") && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (firstWord == "nat")
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
else if (firstWord == "interface")
{
var result = lines.Substring(line1.LastIndexOf('!') + 1);
TextBox3.Text = TextBox3.Text + "\r\n" + result;
}
but I get only one line as output
In case you want to keep your algorithm, this will work for you.
var lines = File.ReadAllLines("C:\\My File2.txt");
int i;
for (i = 0; i<lines.Length;i++)
{
var line1 = lines[i];
if (line1 == "!" || line1 == " ") continue;
if (line1.StartsWith("access-list")) && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (line1.StartsWith("nat"))
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
if (line1.StartsWith("interface"))
{
var str = line1;
while (!Equals(lines[i + 1], "!"))
{
str += lines[i + 1];
i++;
}
TextBox3.Text = TextBox3.Text + "\r\n" + str;
}
}
As per the file structure shown by you interface and ip address are on different lines. So you won't get it in same iteration of for loop. When you find that firstWord == "interface" you will need to set a flag that will tell you that next line is ip address and in next iteration check if that flag is true parse the current line as ip address and process it the way you want.
You should use "File.ReadAllText" instead of "File.ReadAllLines". "File.ReadAllText" returns a string with the complete text file text. After that, you can use the "String.Split" method to generate a string array.
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
Each index of "seperatedStrings" contains what you want.
UPDATE: Here is a code snippet, that can help:
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
foreach (var oneString in seperatedStrings)
{
if (oneString.Contains("access-list"))
{
Console.WriteLine("Access-List: " + oneString);
}else if (oneString.Contains("nat"))
{
Console.WriteLine("Nat: " + oneString);
}else if (oneString.Contains("interface"))
{
Console.WriteLine("Interface: " + oneString);
}
}
This is the output of my code snippet:
I created a small function to catch a string between strings.
public static string[] _StringBetween(string sString, string sStart, string sEnd)
{
if (sStart == "" && sEnd == "")
{
return null;
}
string sPattern = sStart + "(.*?)" + sEnd;
MatchCollection rgx = Regex.Matches(sString, sPattern);
if (rgx.Count < 1)
{
return null;
}
string[] matches = new string[rgx.Count];
for (int i = 0; i < matches.Length; i++)
{
matches[i] = rgx[i].ToString();
//MessageBox.Show(matches[i]);
}
return matches;
}
However if i call my function like this: _StringBetween("[18][20][3][5][500][60]", "[", "]");
It will fail. A way would be if i changed this line string sPattern = "\\" + sStart + "(.*?)" + "\\" + sEnd;
However i can not because i dont know if the character is going to be a bracket or a word.
Sorry if this is a stupid question but i couldn't find something similar searching.
A way would be if i changed this line string sPattern = "\\" + sStart + "(.*?)" + "\\" + sEnd; However i can not because i don't know if the character is going to be a bracket or a word.
You can escape all meta-characters by calling Regex.Escape:
string sPattern = Regex.Escape(sStart) + "(.*?)" + Regex.Escape(sEnd);
This would cause the content of sStart and sEnd to be interpreted literally.
In my database, I store phone numbers like this "7279884545". One solid string with no spaces.
In my class that stores the phone number info, I have a function that will add the correct punctuation.
public static String beautifyPhoneNumber(String number, String extension)
{
String beautifulNumber = "";
if (!String.IsNullOrEmpty(number))
{
beautifulNumber = "(" + number.Substring(0, 3) + ") " +
number.Substring(3, 3) + "-" +
number.Substring(6, 4);
}
if (!String.IsNullOrEmpty(extension))
{
beautifulNumber += " x" + extension;
}
return beautifulNumber;
}
And here is how I have the variable in the class itself.
private string _PhonePrimary;
[DisplayName("Phone Primary")]
public string PhonePrimary
{
get
{
if(this._PhonePrimary != null)
{
this._PhonePrimary = beautifyPhoneNumber(this._PhonePrimary, this.Extension);
}
return this._PhonePrimary;
}
set
{
this._PhonePrimary = value;
}
}
This works fine most of the time. The numbers are outputted to the screen in a "(727) 988-4545" or "(727) 988-4545 x12" if there is an extension for that record in the database.
The problem comes when I do a HttpPost request. The model information that is inside of the post request looks like this.
_PhonePrimary = "(727) 988-4545"
PhonePrimary = "(((7) 2) -7) -"
As noted, it looks like you're calling beautifyPhoneNumber on a number you've already beautified.
Here's an implementation using regular expressions that should get you started:
public static String BeautifyPhoneNumber(string numberToBeautify)
{
//The below gives us capture groups for each
//individual piece of the number.
var regularExpression = new Regex(#"(\d{3})(\d{3})(\d{4})(x\d*)?");
//This matches a number that's already been beautified,
//so we can guard against beautifying twice.
var alreadyBeautifulExpression = new Regex(#"(\(\d{3}\)) (\d{3})-(\d{4}) ?(x\d*)?");
var beautifulNumber = string.Empty;
var separator = "-";
var space = " ";
//This prevents us from accidentally beautifying
//something more than once
//You could also guard against this in your getter using a
//IsBeautified extension, using the alreadyBeautifulExpression above
if (alreadyBeautifulExpression.IsMatch(numberToBeautify))
{
return numberToBeautify;
}
//Trying to protect against invalid input... May be insufficient,
//Or unnecessary
if (string.IsNullOrEmpty(numberToBeautify)
|| regularExpression.Matches(numberToBeautify).Count <= 0)
{
return beautifulNumber;
}
GroupCollection groups = regularExpression.Matches(
numberToBeautify)[0].Groups;
//More protection against invalid input
if (groups.Count < 3)
{
return beautifulNumber;
}
//Given "7689131234",
beautifulNumber += "(" + groups[1] + ")" + space; //gives us "(768) "
beautifulNumber += groups[2] + separator; //gives us "(768) 913-"
beautifulNumber += groups[3]; //gives us "(768) 913-1234"
//If we have an extension, we add it.
if (groups[4] != null)
{
beautifulNumber += space + groups[4];
}
return beautifulNumber;
}
Given inputs of:
7279884545
7279884545x12
(727) 988-4545
This returns:
(727) 988-4545
(727) 988-4545 x12
(727) 988-4545
I have this problem
string text = Html.Raw(immobileTmp.Localita + "\n" + immobileTmp.PrezzoVendita).ToString();
#Html.ActionLink(text, "DettaglioImmobile", "Immobili", new { id = immobileTmp.Id }, null)
but then no new line is in output just <br /> between the 2 strings.
Then I tried
string text = Html.Raw(HttpUtility.HtmlEncode(immobileTmp.Localita + "\n" + immobileTmp.PrezzoVendita).Replace("\n", "<br/>")).ToHtmlString();
#Html.ActionLink(text, "DettaglioImmobile", "Immobili", new { id = immobileTmp.Id }, null)
but had no better luck.
Any ideas?
I guess you need to insert two </ br>, did you tried that ?
UPDATE
Try Environment.NewLine, like that:
string text = Html.Raw(immobileTmp.Localita + Environment.NewLine + immobileTmp.PrezzoVendita).ToString();
#Html.ActionLink(text, "DettaglioImmobile", "Immobili", new { id = immobileTmp.Id }, null)
Try this:
String s1 = (immobileTmp.Localita).ToString() + " ";
String s2 = (immobileTmp.PrezzoVendita).ToString();
String s = s1 + s2
StringBuilder sb = new StringBuilder(s);
int i = 0;
while ((i = sb.indexOf(" ", i + s1.Length)) != -1) {
sb.replace(i, i + 1, "\n");
}
string text = Html.Raw(s);
If you join the strings with Environment.NewLine wrapping the tag in a <pre> splits the lines as you want, as in this sample:
#{
string sep = Environment.NewLine;
string text = Html.Raw(immobileTmp.Localita + sep + immobileTmp.PrezzoVendita).ToString();
}
<pre>
#Html.ActionLink(text, "DettaglioImmobile", "Immobili", new { id = immobileTmp.Id }, null)
</pre>
Gotcha: the text will be formatted as monospaced (because of the <pre>) but CSS can take care of that (<pre class="blah">...).