Posts Tagged ‘JavaScript’

It is a citation of an article that I liked very much

 

How to use regular expressions in JavaScript?

After having examined the theoretical basis and syntax of regular expressions, it is important to know how to use this knowledge in productive terms. In fact, although the rules are common, every programming language uses its own routines: in this article we will deal with the implementation of regex in JavaScript and the main methods associated with their management.

The regular expressions in JavaScript are created as simple strings, delimited by forward slash, followed by some special characters, called flags, which modify the search methodology. We might thus have a variable (or more precisely a literal):

var regex = /modelloRegex/flags;

The model can be any regular expression, while for the flags the three characters g, i or m can be used:

  • g: the model is searched in the entire string, instead of stopping after the first occurrence found.
  • i: the search doesn’t keep track of the difference between characters capital/small.
  • m: the search is executed even after the end of the first text line.

A first simple example of a regular expression could be that of the search for a string:

var regex = /Your Inspiration Web/i;

Find in the hypothetical text the string “Your Inspiration Web”, irrespective of eventual differences between capital and small letters. Or we can reuse the regular expression used to verify a date:

//search a date
var regex = "/\d{2}-\d{2}-\d{4}/g";

However, there are some variations in the implementation  of regular expressions in Javascript: that of the metacharacter ‘full stop’, or rather “every character”, is maybe the most relevant. In fact, the character ‘new paragraph’ is not corresponded when flag m is set.  As a remedy a whole class of characters and its negation, often in the form of “[\s\S]“, can be used. But what does it mean? By checking the table of the previous article you can notice that the class ‘\s’ refers to “every spacing character”.  By adding  ‘\S’ which stands for “all characters which are not spaces” practically we are saying “take all spaces and all characters which are not spaces”; in a few words “all characters”.

The one of the full stop is the only absence worth mentioning  for a ‘normal’  use of the regex in Javascript (there are other differences). A question that arises at this moment is: how to test our regular expressions in JavaScript?

The RegExp Object

In reality in JavaScript all regular expressions  (even the examples mentioned above) are an example of the RegExp object. It’s not relevant to this scope knowing  programming with objects: enough bearing in mind that an object is a structure (such as an array) which has properties (the attributes) and behaviors (the methods). The methods and the attributes belong to the object they refer to and the syntax to recall them is the following:

/* this is denominated "dot notation", for the use of the full stop */
object.attribute;
 
object.method(parameters);

The relevant methods on a RegExp object are two: test and exec. The first performs a test, exactly, of a regular expression on a string, verifying that in the latter there is at least a correspondence. The second instead, restores the information at the eventual occurrence found in the string.

With regard to the attributes worth mentioning lastIndex, which contains the position of the next character to be examined by the regex, and source, which contains the string of the regular expression itself.

Before testing these functions, we create a html page for the tests:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="it" lang="it">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Regular expressions in JavaScript | Your Inspiration Web</title>
</head>
<body>
<h1>Test page for the regular expressions </h1>
 
<script type="text/javascript">
/* Here go our tests */
</script>
</body>
</html>

We will write our JavaScript code inside the tag “script” in the bottom of the page.

The test() method

The test method accepts as parameter a string to which apply the regular expression, and has as a return value a boolean: true, if the string corresponds to the regular expression, false otherwise.

As a first example of the test method, let’s search in a string the correspondences of the regex /CaSa/i:

/* Create regular expression non distinguishing between capital and small letters */
var regex = /CaSa/i;
/* Set the string on which to search */
var str = "Home sweet home"
/* if there's a correspondence, display a message */
if( regex.test(str) ){
    /* action to execute if there's a correspondence */
    alert("Correspondence Found");
}

Let’s analyze step by step this portion of the code. We have:

  1. created our regular expression, in this case a simple string, setting the case-insensitive flag;
  2. initialized the string which will act as search text, in reality this will be represented by the values of a form, or the text taken from a web page;
  3. used the test method in its most congenial environment, an if construction, if there is a correspondence it executes relative action, otherwise proceeds with the next code.

Notice how, after having created the regular expression, we have recalled the “test” method making use of the  dot-notation: recalling “test” without putting before the name of the object will result in an error.

The exec method

Using the same regular expression and the same string, let’s see how the “exec” method functions. The later takes as a parameter a string to which apply the regex, but has as a return value an array containing the found occurrence. Such array has an attribute, index which contains the occurrence position within the string (the character number from the beginning of the string, more precisely).

Let’s see a simple example:

/* Create the regular expression */
var regex = /CaSa/i;
/* Set the string on which to search */
var str = "Oh, Home sweet home"
var resultat = regex.exec(str);
 
/* print string found as correspondence */
alert(result[0]); //Home
/* print position on the string in which a
 * correspondence was found: starts from 0 */
alert(result.index); //4

The creation of the regular expression and that of the string is identical to the previous one. The first difference is the return value of the method, which is saved in the “result” variable. This variable is an array containing in the first position the occurrence of the regular expression found on the string, while in the “index” attribute is saved the position of the occurrence of the string.

An interesting thing to note is that, by repeating the execution of the “exec” method without specifying the “g” flag, always and only the first occurrence is obtained:

/* Create the regular expression */
var regex = /Home/i;
/* Set the string on which to search */
var str = "Oh, Home sweet home"
 
var result = regex.exec(str);
/* print string found as correspondence */
alert(result[0]); //Home
/* print position on the string in which a
 * correspondence was found: starts from 0 */
alert(result.index); //4
 
result = regex.exec(str);
result = regex.exec(str);
result = regex.exec(str);
result = regex.exec(str);
 
/* the string is always the same */
alert(result[0]); //Home
/* and it's always the first, the one in position 4 */
alert(result.index); //4

In order to allow JavaScript to search successive occurrences of the regex you have to, as emphasized, use the “global” flag in the definition of the regular expression:

/* Create the regular expression: I have specified the g flag */
var regex = /Home/ig;
/* Set the string on which to search */
var str = "Oh, Home sweet home"
 
var result = regex.exec(str);
/* print string found as correspondence */
alert(result[0]); //Home
/* print the position on the string in which a
 * correspondence has been found: starts from 0 */
alert(result.index); //4
 
result = regex.exec(str);
 
/* the string  */
alert(result[0]); //Home
/* this time is the second occurrence, the one in position 15 */
alert(result.index); //15

By specifying the global flag we inform JavaScript that it has to continue the search of the text (a little bit like the “Find next” function of text editors): when there are no longer any occurrences the “exec” method will return the “NULL” value, which we have to manage adequately.

Final considerations

Regular expressions can significantly simplify the management of a web application. It has to be mentioned that the engine of regex requires an extremely high CPU percentage, thus it’s good to use them with wariness, verifying that there are no other faster ways to obtain the same result. For example, wishing to search all lines of a string which end in a semicolon, you might be tempted to use the regular expression:

var regex = /;$/;

This simple regular expression could engage your browser for various seconds (even minutes, in case of very long texts): this because the search is not executed only at the end of the string, instead it starts from the first character, examining them one by one, until the end, and then show the results. But how to improve this search?

Regular expressions are useful when there are no hypothesis on the text: in this case, instead, we only want to know if the last character is a semicolon. Why not execute the test only on the last character then?

var str = "Hello everybody;";
if( str.charAt(str.length - 1) == ";" )
    alert("The string ends in a semicolon");

As you saw I used the charAt method to retrieve the last character and confront it with my search string.

In general thus, when you deal with the search or substitution of simple strings, it could be a good idea to experiment first with the JavaScript methods which operate on the strings (charAt, indexOf, slice, substr, substring), and use regular expressions if it’s impossible to find an alternative solution.

Advertisements

I think that article is very useful so I post it here:

“Over the last five years, thanks largely to the rise of frameworks such as jQuery and Prototype, JavaScript has risen to become a first tier language for scripting on the web. This increased popularity and ease of use, has led to the creation of fully fledged applications such as Gmail, which contain thousands of lines of JavaScript code that required teams of talented developers to create.

As a result of this increasing complexity however, when something does go wrong developers need powerful debugging tools in order to quickly root out the cause of the issue and fix it efficiently. A simple var dump via the alert() dialogue simply won’t cut it anymore.

In this tutorial I’ll outline some of the features of modern developer tools that you can use today to help make debugging your JavaScript less painful. We’ll focus primarily on the Chrome developer tools and Firebug but many of these features are available in other tools such as Opera Dragonfly.

The Console – an overview

In most developer tools your best friend is the Console; a multiple purpose panel utilised for error logging, inspection of the DOM, debugging JavaScript and much more. Depending on your browser, it’s simple to launch this panel at any time using:

  • Chrome dev tools and Opera Dragonfly – Ctrl + Shift + I
  • Firebug – F12

To aid you with debugging scripts, the console panel will automatically display any errors in your code which occurred during execution. A file and line number are provided next to each error and clicking the message will jump to that line for inline debugging – handy!

No more alerts() – logging data to the console

The console isn’t just for passively displaying errors however. It also responds to commands you pass to it via the Console API and the Command Line API. Perhaps the best known and most helpful tool is the .log() command.

When writing any form of code it’s helpful to be able to print the value of a variable in order to inspect it. In times gone by a developer might have used the alert() dialogue to provide a visual print out.

Nowadays a better solution is the console.log method which prints the value passed to it to the Console panel like so:

  1. console.log(&ldquo;Captain&rsquo;s Log&rdquo;); // prints &ldquo;Captain&rsquo;s Log&rdquo; on the Console panel

We might use this to print the value of a calculated variable. For example:

  1. function calcPhotos() {
  2.        total_photos_diff = total_photos – prev_total_photos;
  3.        // Log to the Console
  4.        console.log(total_photos_diff);
  5. }

The benefit of this approach over the use of the alert() dialogue is that code execution is not halted and therefore we can print the result of a variable multiple times and watch it change without requiring intervention.

  1. var t = 3,
  2.         p = 1;
  3. function calcPhotos(total_photos, prev_total_photos) {
  4.         var total_photos_diff   = total_photos – prev_total_photos;
  5.         // Log to the Console
  6.         console.log(total_photos_diff);
  7.         // Update values
  8.         t = t*1.3;
  9.         p = p*1.1;
  10. }
  11. setInterval(function() {
  12.         calcPhotos(t,p);
  13. },100);

Distinguishable logging

In the example above the loop causes many variables to be logged to the Console. It’s easy to see how quickly it becomes visually overwhelming if lots of variables are dumped.
Many people are aware of the standard log function, but it’s also useful to know that there are other Console API commands which allow you to distinguish between different types of data being logged to the Console. Perhaps most useful of these are:

console.info(): provides a visual “info” icon and colour coding (blue) to denote a “Info” log call. Useful for denoting when something important is about happen

console.warn(): provides a visual “warning” icon and colour coding (yellow) to denote a “Warn” log call. Useful to log when something is going outside an acceptable range

console.error(): provides a visual “error” icon and colour coding (red) to denote a “Error” log call. Useful for denoting when something has caused an error condition which you need to highlight

Note: Chrome dev tools don’t currently provide any visual distinction between the different types of logging.

Grouping related log calls

Using alternative logging calls provides a semantic and visual distinction between the information being printed into the console and can aid readability. We might still hope to improve this further by grouping our error messages into blocks of related calls. We can do this using console.group():

  1. // Start 1st Grouping
  2. console.group(“Photo calculation”);
  3.       console.info(“Total difference is now ” + total_photos_diff);
  4.       console.log(total_photos_diff);
  5. console.groupEnd(); // end group
  6. // Start 2nd Grouping
  7. console.group(“Incrementing variable”);
  8.        console.log(“Total photos is now: ” + t);
  9.        console.log(“Prev total photos is now: ” + p);
  10. console.groupEnd(); // end group

This produces a grouped output in the Console. The visual representation is different in different tools. Here’s how it looks in Opera Dragonfly:

The examples above just scratch the surface of what’s possible with the Console API. There are many other useful commands available to you. I recommend reading through the Firebug official Wiki page for a list of commands, although it’s worth noting that support across different tools isn’t necessarily universal.

Pausing script execution

Logging to the console is useful but things can quickly get out of hand if you code is executing quickly and you’re trying to keep track of multiple variables.

To make life easier we can use debugging tools to pause code execution at a particular points, allowing you to assess the current code status at leisure. The most common way to pause code execution in modern dev tools is to use Break Points.

Working with break points

To set a break point navigate to the ‘Scripts’ tab and select the script you’re working on from the list. Now find the line where you’d like to pause execution and click in the margin to activate the breakpoint – a visual indicator should appear. Now reload the page and execution will be halted at the specified point:

With execution paused you can now hover your cursor over any variable and the debugger will bring up a tooltip with information about it’s value at the current time.

Once you’re ready you can then choose to continue code execution using one of the Execution Control Buttons which are usually located at the top of the side panels. The options available to step through the code are:

  • “Continue”: continues code execution until another breakpoint is encountered.

  • “Step Over”: steps through the code line by line so that you can see how each line effects the variables being updated. If your code calls another function the debugging will not jump into its code. Instead it will be “stepped over” and the focus will remain with the current function.

  • “Step Into”: similar to Step over, except that when you click “Step Into” at function call, the debugger moves its execution to the first line in the function definition.

  • “Step Out”: if you have stepped into a function definition by clicking Step Into button, clicking the Step out button causes the remainder of the function definition to be executed and the debugger moves its execution to its parent function.

As you step through, you can use the side panels to help you keep track of changes in your code’s state including updates to local, closure and global scope variables.

Conditional Breakpoints

As breakpoints stop code execution it is sometimes desirable to only have them fire when certain conditions are met. If your code uses a loop which fires every 50ms for example, you probably don’t want the debugger to halt on each iteration. We can avoid this using a
conditional breakpoint.

In the example above code execution will now only break when the total_photos_diff variable is greater than 200 saving us a lot of extra clicks in the debugger. To activate a conditional breakpoint, right click on the breakpoint in the margin and choose ‘Edit Breakpoint’ to reveal the conditional breakpoint dialogue.

Setting Breakpoints from code

It’s not always convenient or even desirable to set breakpoints using the dev tools interface.
Sometimes it’s just easier to launch the debugger directly from you code. This can be done via the use of the debugger keyword. The example below shows how you could pause code execution via a conditional statement in your code

  1. if (total_photos_diff > 300) {
  2.           debugger;     // launch the debugger and pause execution
  3. }

Other ways to pause execution

Besides setting breakpoints manually, developer tools also provide you with a number of opportunities to halt code execution depending on various scenarios.

Break on DOM mutation

If you’d like to debug a piece of code which is handling a DOM mutation, then developer tools provide a way for you to pause code execution when a DOM node changes.

Using the Elements panel, right click on the node which is being modified and you’ll be provided with a set of options to Break on DOM alteration. Reload and the next time the element changes script execution will halt.

You can keep track of which Breakpoints you have set using the DOM Breakpoints side panel.

Pause on all/uncaught exceptions

Most dev tools allow you to pause script execution when an exception is encountered. In Chrome dev tools this functionality can be toggled using the ‘Pause’ icon on the bottom row of the interface.

You can choose whether to break on all exceptions, or simply on those exceptions which aren’t handled by your script. The example below shows an uncaught exception and one which is ‘caught’ (handled via try/catch).

  1. var t = 3,
  2.         p = 1;
  3. function calcPhotos(total_photos, prev_total_photos) {
  4.         var total_photos_diff   = total_photos – prev_total_photos;
  5.         // Start 1st Grouping
  6.         console.info(“Total difference is now ” + total_photos_diff);
  7.         // Update values
  8.         t = t+5;
  9.         p = p+1;
  10.         // Uncaught exception – will pause
  11.         if (total_photos_diff > 300) {
  12.                 throw 0;
  13.         }
  14.         // Exception is caught via the try/catch
  15.         // Will only pause when “pause on ALL expections” is active
  16.         if (total_photos_diff > 200) {
  17.                 try {
  18.                         $$(‘#nonexistent-element’).hide();
  19.                 } catch(e) {
  20.                         console.error(e);
  21.                 }
  22.         }
  23. }
  24. setInterval(function() {
  25.         calcPhotos(t,p);
  26. },50);

An introduction to the Call Stack

If you encounter an error in your script then pausing on exceptions will halt execution at the point in your code where the error was thrown. However what if it’s not obvious what has caused the error? What has led to the error occurring? How do we discover this information?

When script execution is halted you will notice the panels on the right hand side of the tools interface which provide a wealth of useful information, the most valuable of which is perhaps the call stack.

The call stack shows the full execution path that led to the point where code was paused providing you a birds-eye view of the code flow that led to the error.

In the example below I’ve intentionally thrown an error in the incrementValues() function which has brought up the debugger. The developer tools show the full call stack that led to the error, which allows me to step back through the code flow to determine any potential issues.

Further reading and resources

Hopefully the examples above have provided a useful overview of some of the methods at your disposal to make debugging your JavaScript just that little bit easier.

However, this article outlines just a flavour of what can be accomplished. To learn more I thoroughly recommend spending some time with the following resources in order to really understand the true power of your developer tools:

  • Firebug Wiki: Firebug is the original “developer tool” and it’s Wiki has a wealth of informationon the various API’s and tools available.
  • Chrome Developer Tools docs: the Chrome dev tools docs provide a wealth of information on getting the most from their tools. Even the most experienced will learn something here.
  • Video: “Chrome Dev Tools Reloaded”: filmed at Google I/O 2011, Paul Irish and Pavel Feldman provide a excellent overview of the power of the Chrome dev tools. A must watch!
  • Opera Dragonfly Debugger docs: even if you don’t use Opera on a daily basis the concepts described in their documentation are applicable across most developer tools.
  • Chrome dev tools cheatsheet: a handy print out for working with Chrome Dev tools.”

An article from frontend developer David Smith