I am creating a custom server control with a property that accepts a String as input. What is the correct way to handle whitespace/tabs & newlines? For example,
<prefix:MyControl runat="server"
Property="This is a long text string which is manually
wrapped in the VS text editor on multiple
lines."
>
</prefix:MyControl>
This returns something similar to
"This is a long text string which is
manually\r\n
wrapped in the VS text
editor on multiple\r\n
lines."
Is there a special attribute I can apply to the propery to help with this? I have checked Metadata Attributes for Custom Server Controls Or do I need to manually strip the linebreaks and extra spacing?
Discovered a Regular Expression solution which finds multiple whitespace characters preceded by a line break and replaces matches with a single space.
private string property;
[Bindable(true)]
public string Property {
get { return property; }
set {
property = Regex.Replace(value, #"(\n|\r|\r\n)\s+", " ");
}
}
Related
Our CMS is (I suppose correctly) encoding comma characters in URLs. So instead of being "?values=1,2,3" the CMS is rendering "?values=1%2c2%2c3". This in itself is not a problem however the external system that these links are pointing at cannot handle the encoded commas and only works if we pass actual commas in the query string.
We already have a Regex clean-up tool that processes the HTML pre-render and cleans out non XHTML compliant mark-up. This is an old CMS running on ASP.Net v2.
My question is what regular expression would be required to swap out all occurrences of "%2c" for a comma, but only where this text exists within an anchor tag. I've been easily able to swap out all instances of %2c but this runs the risk of corrupting the page elsewhere if that string happened to be used for a non-URL purpose.
I'm using .Net and System.Text.RegularExpressions. We have an XML file that contains all of the Find and Replace rules. This gets loaded at runtime and cleans the HTML. Each rule consists of:
Text to find - e.g. "<script>"
Text to replace - e.g. "<script type='text/javascript'>"
We then have some C# that loops over each of the rules and does the following:
// HTML = full page HTML
Regex regex = new Regex(searchTxt, RegexOptions.IgnoreCase);
HTML = regex.Replace(HTML, replaceTxt);
Simple as that. I just can't get the right regex syntax for our specific scenario.
Many thanks for your help.
Here is a complete C# console app that hopefully explains my scenario
class Program
{
static void Main(string[] args)
{
string html = GetPageHTML();
string regexString = "(<a href=).*|(%2c)";
string replaceTxt = ",";
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline;
Regex regex = new Regex(regexString, options);
// We are currently using a simple regex.Replace
string cleanHTML = regex.Replace(html, replaceTxt);
// But for this example should we be doing something with the Matches collection?
foreach (Match match in regex.Matches(html))
{
if (match.Success)
{
// do something?
}
}
}
private static string GetPageHTML()
{
return #"<html>
<head></head>
<body>
<a title='' href='http://www.testsite.com/?x=491191%2cy=291740%2czoom=6%2cbase=demo%2clayers=%2csearch=text:WE9%203QA%2cfade=false%2cmX=0%2cmY=0' target='_blank'>A link</a>
<p>We wouldn't want this (%2c) to be replaced</p>
</body>
</html>";
}
}
If .net would support pcre regex you could do something like this:
^(?!<a href=").*(*SKIP)(*FAIL)|(%2c)
That is what you want. Above regex will match only %2c inside anchor tags. But you could achieve the same if you use regex the regex discard technique plus some logic.
If you use below regex, you could match %2c and also capture the %2c string that is within anchor tags:
^(?!<a href=").*|(%2c)
Working demo
So, what you can do is to add logic and to check if the capturing group content is equal to %2c, in that case means that it matches %2c from the anchor tag. Then you can replace that for a comma.
I need to replace all urls in the text IF they are not put into '...' HTML tags yet.
The unconditional way to replace is described here: Recognize URL in plain text.
Here is my implementation of it:
private static readonly Regex UrlMatcherRegex = new Regex(#"\b(?:(?:https?|ftp|file)://|www\.|ftp\.)(?:\([-A-Z0-9+&##/%=~_|$?!:,.]*\)|[-A-Z0-9+&##/%=~_|$?!:,.])*(?:\([-A-Z0-9+&##/%=~_|$?!:,.]*\)|[A-Z0-9+&##/%=~_|$])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static string GetProcessedMessage(this INews news)
{
string res = UrlMatcherRegex.Replace(news.Mess, ReplaceHrefByAnchor);
return res;
}
private static string ReplaceHrefByAnchor(Match match)
{
string href = match.Groups[0].Value;
return string.Format("{0}", href);
}
But how can I ignore those URLs which are already formatted properly?
Please advise.
P.S. I'm using ASP.NET 4.5
P.P.S. I could imagine that one of the solutions could be enhance regex to check for "
From my point of view there are 2 solutions:
Use special libraries to parse your HTML document (if it's proper HTML document). For example, you can use XDocument.Parse. After parsing the document you can easily find out if the element is normal HTML "a" tag or it's just a plain text.
You can suggest that if the link is already formatted properly - it will have "href" prefix before the URL. So, in your regex you can search for all links not having "href=" before them. This could be done either via C# or via regex negative look-around functionality. You can see an example here: Regular expression to match string not containing a word?
I have a list of text files and when one is selected it is read and assigned to a string variable. this string is then pushed to a view : pushView(viewer, string), where the string is displayed in a textarea. I want to also pass the relative path of the file also. Is this possible to pass two strings?
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
if(data!=null){
mainTextField.text = data.toString();
}else{
mainTextField.text = "";
}
}
Yes it is possible. Typically the way I do this in Flex is to add a data property on my view of type Object allowing me to pass any type of object into the view.
In your case I would change pushView(viewer, string) to something like pushView(viewer, data) where data is some object that stores all the data you need to pass to the view. data might look like:
var data:Object = { text: "my text to display",
relativePath: "the/relative/path" };
I'm looking at server controls for the first time, and I've a question about this code:
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? "[" + this.ID + "]" : s);
}
set
{
ViewState["Text"] = value;
}
}
I do not understand why this control returns the [id] or the text that is set. I do not see how this makes any sense. Is this just for demonstration or is there a reason for returning the id?
Thanks
It looks like an example that will show the controls ID if the controls .Text property has not been set.
This is a bit of a "debug" procedure to show that the control is actually rendering even though it hasn't got any data set in it's Text property.
Makes no sense to me. If I'm asking for text, then I expect if there is no text to get either an empty string or null.
If there's nothing been set for the Text property, in ViewState with other words, then this.ID gets returned.
There's not really a meaning for it but it'll show some text in the Property pane of Visual Studio and on the designer.
Is there a way to get an ASP.NET textbox to accept only currency values, and when the control is validated, insert a $ sign beforehand?
Examples:
10.23 becomes $10.23
$1.45 stays $1.45
10.a raises error due to not being a valid number
I have a RegularExpressionValidator that is verifying the number is valid, but I don't know how to force the $ sign into the text. I suspect JavaScript might work, but was wondering if there was another way to do this.
The ASP.NET MaskedEdit control from the AJAX Control Toolkit can accomplish what you're asking for.
I know an answer has already been accepted, but I wanted to throw out another solution for anyone with the same problem and looking for multiple workarounds.
The way I do this is to use jQuery format currency plugin to bind user input on the client side. Parsing this input on the server side only requires:
// directive
using System.Globalization;
// code
decimal input = -1;
if (decimal.TryParse(txtUserInput.Text, NumberStyles.Currency,
CultureInfo.InvariantCulture, out input))
{
parameter = input.ToString();
}
The only downfall to this is that the user can have javascript turned off, in which case the RegEx validator running server-side would work as a fall-back. If the control is databound, all you have to do is decimalValue.ToString("{0:c}") , as mentioned by others, in order to display the proper currency formatting.
The cool thing about this is that if the user enters the textbox and it shows $0.00 on the client side, the server-side if statement would return false. If your decimal value isn't nullable in the database, just change decimal input = -1 to decimal input = 0 and you'll have a default value of 0.
Another way to do this might be to place the dollar sign outside to the left of the text box. Is there a real need to have the dollar sign inside of the box or will a simple label do?
decimal sValue = decimal.Parse(txtboxValue.Text.Trim());
// Put Code to check whether the $ sign already exist or not.
//Try making a function returning boolean
//if Dollar sign not available do this
{ string LableText = string.Format("{0:c}", sValue); }
else
{ string LableText = Convert.ToString(sValue); }
string sValue = Convert.ToString(txtboxValue.Text.Trim());
// Put Code to check whether the $ sign already exist or not.
//Try making a function returning boolean
//if Dollar sign not available do this
{ string LableText = string.Format("{0:c}", "sValue"); }
else
{ string LableText = Convert.ToString(sValue); }
In the .CS you could do a pattern match along the lines of,
string value = text_box_to_validate.Text;
string myPattern = #"^\$(\d{1,3},?(\d{3},?)*\d{3}(\.\d{0,2})|\d{1,3}(\.\d{2})|\.\d{2})$";
Regex r = new Regex(myPattern);
Match m = r.Match(value);
if (m.Success)
{
//do something -- everything passed
}
else
{
//did not match
//could check if number is good, but is just missing $ in front
}