ShowUsYour<Blog>

Irregular expressions regularly

August 2003 - Posts

Displaying User Input - Part 2

Back in June I posted a cryptic little entry that highlighted a potential issue that can arise when displaying user input.

http://weblogs.asp.net/dneimke/posts/8566.aspx

By now we all know that, when rendering user input to the browser that it needs to be HtmlEncoded right... but, what about if you need to display user input into a TextBox? HtmlEncoding it will make it unreadable and (as per my initial post) doing nothing with it will leave you exposed if the user entered something like:

 </TEXTAREA><SCRIPT>self.location = 'raceyRhonda.com'</SCRIPT> 

My solution to this problem is to emit the user input into a client-side variable and then load it into the TextBox at runtime. Here is a silly demo the explains what I'm blabbing about:

************ WEB FORM **************** <HTML><body> <form id="Form1" method="post" runat="server"> <P> Enter an expression and it will be emitted into the Textbox on PostBack... <BR> <asp:TextBox id="newTestTextBox" runat="server" TextMode="MultiLine" Rows="5" Columns="40"></asp:TextBox> <asp:Button id="testButton" runat="server" Width="72px" Text="Test" /> </P> <P> <HR width="100%" SIZE="1"> </P> <P>Your pattern is: <BR> <asp:TextBox id="outputTextBox" runat="server" Width="504px" /> <BR> <asp:Label id="outputLabel" runat="server"></asp:Label></P> </form> </body></HTML> ************ CODEBEHIND ************** private void testButton_Click(object sender, System.EventArgs e) { string source = CleanString( newTestTextBox.Text ) ; EmitLoadScript( source ) ; outputLabel.Text = Server.HtmlEncode( newTestTextBox.Text ) ; } private string CleanString( string s ) { string tmp = s ; if( tmp.Trim().Length > 0 ) { tmp = Regex.Replace( tmp, @"(?'cleanItem'[\\\/'""])", "\\${cleanItem}" ).Trim() ; } return tmp ; } private void EmitLoadScript( string s ) { StringBuilder sb = new StringBuilder() ; sb.AppendFormat( @"{0}<script>{0}", Environment.NewLine ) ; sb.Append( @"document.getElementById( """ ) ; sb.AppendFormat( @"{0}"" ).value =""{1}"" ;", outputTextBox.ClientID, s ) ; sb.AppendFormat( "{0}</script>{0}", Environment.NewLine ) ; Page.RegisterStartupScript( "populateTB", sb.ToString() ) ; } 
Posted: Aug 29 2003, 12:31 AM by digory | with 5 comment(s)
Filed under: ,
RegexLib.com - recent additions

Just thought that I'd mention that RegexLib.com has received 10 new patterns this week.  Here's a couple of interesting titbits:

There was a pattern added that matches HTML Color strings:

http://www.regexlib.com/REDetails.aspx?regexp_id=372

A regex posted to the "Dates and Times" category only 4 days ago has already received 8 user comments.  Take a look at how user comments are helping to evolve stronger, better tested expressions here:

http://www.regexlib.com/REDetails.aspx?regexp_id=369

Overall, it appears that the addition of the Rss feed has increased the activity and participation on the site.  You can subscribe to the RegexLib.com feed here:

http://www.regexlib.com/Rss.aspx

Posted: Aug 28 2003, 10:58 PM by digory | with 15 comment(s)
Filed under:
ShowUsYour<Calendar>

I've just uploaded the newest version of the ShowUsYourCode Dhtml Calendar.  This cross-browser started its life over 2 years ago and has evolved into quite a slick unit.  The latest version incorporates some UI/Css related changes that were put forward by one of its users - Caitlin Fegan.

You can see a working demo of the calendar here:

http://www.flws.com.au/CalendarDemo/DhtmlCalendar.html

... and, you can download the .zip'ped bits here:

http://www.flws.com.au/CalendarDemo/CalendarDemo.zip

Feel free to use it in your projects but please, if you create any cool stylesheets for it, please, please send them to me :-)

 

Posted: Aug 28 2003, 10:11 PM by digory | with 7 comment(s)
Filed under: ,
Match opening tags improvements

I've made a couple of alterations to the opening tag regex.

I've changed the non-capturing group that previously grouped attributes to use Atomic Grouping (?>...) so that states are not saved and therefore reducing any uneccessary backtracking. I've also added a negative lookahead assertion at the beginning of that group so that, if the ending tag is found the whole group will fail and I can step out of the group immediately. This also allows me to remove the lazy (...)*? quantifer at the end of the group and allow it to become (...)*

The entire pattern now looks like this:

(?'openTag'<)
    \s*?
    (?'tagName'\??\w+)
    (?>
	(?!=[\/\?]?>)
        \s*?
        (?'attribName'\w+)
        (?:\s*(?'attribSign'=)\s*)
        (?'attribValue'
            (?:\'[^\']*\'|\"[^\"]*\"|\w+)
        )
    )*
    \s*?
    (?'closeTag'[\/\?]?>)

Or, rendered as a single string...

(?'openingTag'<)\s*?(?'tagName'\??\w+)(\s*?(?>(?!=[\/\?]?>)(?'attribName'\w+)(?:\s*(?'attribSign'=)\s*)(?'attribValue'(?:\'[^\']*\'|\""[^\""]*\""|\w+))))*\s*?(?'closeTag'[\/\?]?>)
Posted: Aug 28 2003, 11:27 AM by digory | with no comments
Filed under:
HOW TO: Using RegexSnippets

I was just chatting to Thomas about RegexSnippets and how I use it to test my regex's.  I think that most people haven't cottoned-on to the fact that you can write test modules within RegexSnippets itself.  To use the code IDE do the following:

You can also save code snippets from within the code IDE by selecting File | Save As.  The code snippet gets saved into the "Templates" list in the code IDE.

The most common way of using the code IDE is to generate patterns from the Main Form and then, when you've got the pattern working you can right click in the "Pattern" textbox and choose "Generate Template"; this will copy your current regex and source into a pre-defined Template.  You can also create your own Templates by editing the Xml configuration file in "\My Documents\RegexSnippets\Templates.xml".

All of this stuff is pretty much covered in the Help | Readme file.

Posted: Aug 28 2003, 12:21 AM by digory | with no comments
Filed under: ,
Regex to match opening Tags

While fiddling around in RegexSnippets tonight I concocted this regex to match opening tags and to capture the various elements:

          
(?'openTag'<)
    \s*?
    (?'tagName'\??\w+)
    (?:
        \s*?
        (?'attribName'\w+)
        (?:\s*(?'attribSign'=)\s*)
        (?'attribValue'
            (?:\'[^\']*\'|\"[^\"]*\"|\w+)
        )
    )*
    \s*?
    (?'closeTag'[\/\?]?>)

...and here is a script that I wrote to test it with:

using System ;
using System.Text.RegularExpressions ;

namespace RegexSnippets.Tests
{
    public class Foo
    {
        public static void Main()
        {
            string source = @"<A href="foo"><TD><A> <TABLE id=1 foo="bar">" ;
            string pattern = @"(?'openTag'<)\s*?(?'tagName'\??\w+)(\s*?(?'attribute'(?'attribName'\w+)(?:\s*(?'attribSign'=)\s*)(?'attribValue'(?:\'[^\']*\'|\"[^\"]*\"|\w+))))+\s*?(?'closeTag'[\/\?]?>)" ;

            Regex re = new Regex( 
                    pattern, 
                    RegexOptions.IgnoreCase|RegexOptions.Multiline|RegexOptions.Singleline
                ) ;
             
            for( Match m = re.Match( source ); m.Success; m = m.NextMatch() ) 
            {
                Console.WriteLine( "Open tag = {0}", m.Groups["openTag"].Value ) ;
                Console.WriteLine( "Tagname = {0}", m.Groups["tagName"].Value ) ; 
                
                if( m.Groups["attribName"].Success )
                {
                    for( int i = 0; i < m.Groups["attribName"].Captures.Count; i++ ) {
                        
                        Console.WriteLine( "Attrib Name = {0}", m.Groups["attribName"].Captures[i].Value ) ;
                        Console.WriteLine( "Attrib Sign = {0}", m.Groups["attribSign"].Captures[i].Value ) ;
                        Console.WriteLine( "Attrib Value = {0}", m.Groups["attribValue"].Captures[i].Value ) ; 
                    }
                    
                }


                Console.WriteLine( "Close tag = {0}", m.Groups["closeTag"].Value ) ; 
                Console.Write( "{0}**********************************{0}", Environment.NewLine ) ;

            }
            Console.ReadLine() ; 
        }
    }
}  

Posted: Aug 27 2003, 11:44 PM by digory | with 3 comment(s)
Filed under:
OT: Monkey Business

Primate Programming Inc: The Evolution of Java and .NET Training

Blogging Html

Blogging about mark-up is difficult, I often try to do it with mixed success.  I've been using Word to transfer the colorized mark-up from VS.NET into my blog but, often it will complain about Word's xml formatting.  The new “Word Clean“ function in the .Text blog admin tool not only removes the errant xml metadata but, oftentimes it will remove all coloring!

A good way to add colorized markup to a blog post is to use the MarkItUp.com mark-up colorizer:

http://www.markitup.com/Product/Version2.asp

Paste raw mark-up into the Textbox and press “MarkItUp”.  Checking the checkbox will force the tool to attempt attribute colorization.  Once the mark-up has been colorized just copy and paste the result into the blogging tool.

Posted: Aug 18 2003, 10:14 PM by digory | with 6 comment(s)
Filed under: ,
Computing aggregated data in a DataTable

The other day I was struggling to come to terms with how to perform aggregate queries on a DataTable.  I was able to create calculated columns to display calculated data but, I couldn’t work out how to return aggregated data from a query over a DataTable.

 

Well that all changed today while reading Greg Low’s notes from the recent Australian Tech-Ed.  Basically you just use the Compute method of the DataTable – here’s a little demo that will run a LIKE query over a list of names (using the characters that you enter in the textbox followed by a wildcard):

// Compute documentation
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDataDataTableClassComputeTopic.asp?frame=true

// Expression Syntax
http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemdatadatacolumnclassexpressiontopic.asp?frame=true

// WebForm

<form id="Form1" method="post" runat="server">
    <asp:DataGrid id="namesGrid" runat="server" />
    <P>
        <HR width="100%" SIZE="1">
        <asp:TextBox id="entryTextBox" runat="server"></asp:TextBox>
        <asp:Button id="getResultsButton" runat="server" Text="Get Count" />
    </P>
    <P>
        <asp:Label id="resultLabel" runat="server"></asp:Label>
    </P>
</form>

// Codebehind

private void Page_Load(object sender, System.EventArgs e)
{
   
if
(!IsPostBack)
    {
        DataTable dt = GetData() ;
        namesGrid.DataSource = dt.DefaultView  ;
        namesGrid.DataBind() ;
    }
}


private
DataTable GetData()
{
    DataTable dt =
new DataTable("test"
) ;
    DataColumn dc =
new DataColumn("Name", typeof(string
)) ;
    dt.Columns.Add(dc) ;

   
string[] names = new string[] {"darren", "peter", "robin", "phil", "wayne", "rob", "doug"
} ;

   
for(int
i = 0; i
    {
        DataRow dr = dt.NewRow() ;
        dr[
"Name"
] = names[i] ;
        dt.Rows.Add(dr) ;
    }
   
return
dt ;
}


private void getResultsButton_Click(object
sender, System.EventArgs e)
{
    DataTable dt = GetData() ;
    namesGrid.DataSource = dt.DefaultView  ;
    namesGrid.DataBind() ;
   
int countOfName = (int) dt.Compute("Count(Name)", "Name Like '" + entryTextBox.Text + "*'"
) ;
    resultLabel.Text = countOfName.ToString() +
" results match that query."
;
}

Posted: Aug 18 2003, 10:05 PM by digory | with 14 comment(s)
Filed under: , ,
ICompare langugages

Today one of the guys and I were having a conversation about "stuff"; not particularly interesting or relevant but, nonetheless it was "stuff".  Now this was your typical bored-nerd conversation, you know the one:

If Me.IsThirsty OrElse Me.IsHungry Then
    Me.Goto(Fridge)
    Dim coll As Foods = Me.CurrentLocation.GetContents()
    Dim i As Integer
    For Each f As Food In coll
        Me.Consume(f.RawContent)
        If i > 10 Then : Me.Burp() : End If
        i += 1
    Next   
End If   

The main difference between this senseless conversation and all of the other senseless conversations is that we were "psuedo-ing" in different languages.  He was "psuedo-ing" in VB while I was "psuedo-ing" in some wierd, as yet uninvented version of C#.

Now, if you happpen to find yourself having a mixed context conversation then, you'd better keep this link handy ;-)
 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxgrflanguageequivalents.asp

Posted: Aug 14 2003, 03:43 PM by digory | with 4 comment(s)
Filed under: , , ,
More Posts Next page »