Thursday, July 14, 2011

I Love Regex

regex is awesome. Its powerful, its fun, and it can make you extremely efficient. There are 2 places where regex is most needed.

1) fixing code.
You've seen maybe 3 videos on my youtube channel about using regex with text wrangler.  I don't know about you, but I have to fix code sometimes.  And sometimes, it requires replacing some text a thousand times.  Or say you have a long list of stuff, and you wanna make it into a comma list.  That regex is simply

Find:
\r
Replace with:
,

So, it's quite often that I need to replace a bunch of stuff in some HTML or PHP, or even CSS and knowing regex makes this task very simple.  If you didn't know regex, you would either have to pay some kid to do the same task 1000 times, or you would have to waste your time doing it.  Or, if you didn't know how to use regex in your text editor, you'd have to write a script to do the replacement for you.  So get to know your text editor. This function is also called "grep".

2) Pattern Matching
This is pretty generic.  This can mean anything from page scraping, to dom crawling, to email syntax checking, to curse word validation.  It's all pattern matching.
There are 2 extremely useful regex you should know about.

1) match until character.  This is great for DOM crawling.  But it's also great for email addresses.  The regex is [^c]+  Where "c" is the character your are matching until.  So to match every div on the page, you would do div[^>]+  That would match <div however many times it was on your page. If you wanted the closing > you would just add it on.  div[^>]+>  ta da.

2) match until string.  This is extremely useful, and a lot of people never know about it. Lets say you have a div of class "hello" and inside maybe 20 divs down, is a class "world"  You can't use the "match until character" to find "world".  You would use this awesome regex.

hello(?:(?!world).)+

Complicated right?  yea, well just copy and paste it when you need to use it.  Lets explain.

  1. We start with hello. Pretty simple.

  2. Then we first use a negated lookahead.  (?!world).  Which basically says "match one time the string "world" NOT followed by anything. (which is the .)  So again, were matching 1 time, the word "world" that is NOT followed by anything.

  3. Then, we need to not just match 1 time. That would just give us 1 character. We need to match everything until we get there. Just like the "match until character" had the +, we need a + here as well.

  4. But you can't just add a +.  And you can't wrap the whole thing in square brackets like a normal regex.  So we need to wrap in parentheses so we can use the +  ((?!word).)+

  5. BUT, we have a problem that we just used parentheses, which are going to capture the result.  So we now need to NON CAPTURE those parentheses so they stay out of the way.
    (?:(?!world).)+

And that is the "match until string".

You could also use another regex instad of a string.  say we wanted to find hello world or hello planet.
(?:(?!world|planet).)+

Heres a video explaining this if I didn't do a good job writing it.

Tuesday, July 5, 2011

Source Code Release - Load After Scroll / ForeverScroll

The video



Also to note:
You could pass in a number into the load function and load different content, you don't always have to load the same thing over and over, that was just for the example.

<html>
<head>
 <style type="text/css">
  #flickr {
   height:600px;
   overflow-x:hidden;
   width:800px;
  }
  .flickr_results, .loading {
   padding:10px;
   border-radius:5px;
   background:#eee;
   color:#555;
   margin:10px;
   font-family:helvetica;
   font-size:11px;
   font-weight:bold;
  }
  .loading {
   background:#000;
   color:white;
  }
 </style>
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 <script type="text/javascript">
  
  var loading = true;
  
  function loadFlickr() {
   var url = "http://api.flickr.com/services/rest/?&method=flickr.photosets.getPhotos&api_key=4ef2fe2affcdd6e13218f5ddd0e2500d&photoset_id=72157619415192530&format=json&jsoncallback=?";
   $.getJSON(url, function(data) {
    var photos = data.photoset.photo;
    $.each(photos, function(i,photo) {
     var title = photo.title;
     $("#flickr").append("<div class='flickr_results'>"+title+"</div>");
    });
    
    // once we've loaded
    // kill the loading stuff
    loading = false;
    $(".loading").remove();
    
   });
  }
  
  $(function() {
   
   // load initial photos
   loadFlickr();
   
   // scroll event of the main div
   $("#flickr").scroll(function() {
   
    // get the max and current scroll
    var curScroll = $(this)[0].scrollTop;
    var maxScroll = $(this)[0].scrollHeight - $(this).height();
    
    // are we at the bottom?
    if( (curScroll == maxScroll) && loading == false) {
    
     // when you start, set loading
     loading = true;
    
     // add the loading box
     $("#flickr").append("<div class='loading'>Loading...</div>");
     
     // scroll to the bottom of the div
      $(this)[0].scrollTop = $(this)[0].scrollHeight - $(this).height();
     
     // load more photos
     loadFlickr();
    } 
   });  
   
  });
 </script>
</head>
<body>
 <div id="flickr">
 
 </div>
</body>
</html>

Source Code Release - CSS3 Animation Menu

Here is the video



<html>
<head>
 <style type="text/css">
  body {
   background:#9cb4b3;
  }
  div.moving_arrow {
   width:640px;
   height:25px;
   margin:50px auto;
  }
  .moving_arrow ul {
   margin:0;
   padding:10px;
   border-radius:8px;
   height:inherit;
   width:inherit;
   background:-webkit-gradient(
    linear, 
    left top, 
    left bottom, 
    color-stop(0, #fff),
    color-stop(1, #e5e5e5)
   ) #e5e5e5;
   -webkit-box-shadow:0px 0px 6px #555;
  }
  .moving_arrow ul li {
   list-style:none;
   float:left;
   margin-right:11px;
  }
  .moving_arrow ul li a {
   display:block;
   float:left;
   padding:4px 8px 8px 8px;
   font-family:helvetica;
   text-shadow:0px 1px 1px white;
   color:#666;
   font-weight:700;
   text-decoration:none;
  }
  .moving_arrow li img {
   float:left;
   padding:4px 3px 8px 8px;
  }
  #arrow {
   width:12px;
   -webkit-transition:margin-left 400ms ease-out;
   margin-left:50px;
  }
  #arrow svg, #arrow polygon {
   width:12px;
  }
  #arrow.home {margin-left:54px;}
  #arrow.apps {margin-left:150px;}
  #arrow.blog {margin-left:233px;}
  #arrow.about {margin-left:339px;}
  #arrow.support {margin-left:457px;}
  #arrow.contact {margin-left:569px;}
  #arrow polygon {
   text-shadow:0px 1px 1px black;
   -webkit-box-shadow:0px 0px 6px black;
  }
  
 </style>
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
 <script type="text/javascript">
  $(function() {
   $(".moving_arrow ul li a").mouseover(function() {
    $("#arrow").removeAttr("class").addClass($(this).attr("class"));
    return false;
   });
  });
 </script>
</head>
<body>
 <div class="moving_arrow">
  <ul>
   <li>
    <img src="icon.png"/>
    <a class="home" href="">Home</a>
   </li>
   <li>
    <img src="icon.png"/>
    <a class="apps" href="">Apps</a>
   </li>
   <li>
    <img src="icon.png"/>
    <a class="blog" href="">Blog</a>
   </li>
   <li>
    <img src="icon.png"/>
    <a class="about" href="">About Us</a>
   </li>
   <li>
    <img src="icon.png"/>
    <a class="support" href="">Support</a>
   </li>
   <li>
    <img src="icon.png"/>
    <a class="contact" href="">Contact</a>
   </li> 
  </ul>
  <div id="arrow">
   <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="12px" height="7px">
    <polygon id="arrow_thumb_shadow" points="0,0 6,7 12,0" fill="#333"/>
    <polygon id="arrow_thumb" points="0,0 6,6 12,0" fill="#e5e5e5"/>
   </svg>
  </div>
 </div>
</body>
</html>