<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>regex Archives - rweber.net</title>
	<atom:link href="https://www.rweber.net/tag/regex/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.rweber.net/tag/regex/</link>
	<description>trying to be a mile wide AND a mile deep</description>
	<lastBuildDate>Sun, 01 Jul 2018 11:22:21 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
<site xmlns="com-wordpress:feed-additions:1">37896774</site>	<item>
		<title>Bookmarkable Ajax-Driven Pages</title>
		<link>https://www.rweber.net/javascript/bookmarkable-ajax-driven-pages/</link>
					<comments>https://www.rweber.net/javascript/bookmarkable-ajax-driven-pages/#respond</comments>
		
		<dc:creator><![CDATA[Rebecca]]></dc:creator>
		<pubDate>Mon, 09 Jul 2018 12:00:56 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[UX]]></category>
		<guid isPermaLink="false">http://www.rweber.net/?p=40496</guid>

					<description><![CDATA[<div><img width="212" height="300" src="https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations-212x300.jpg" class="attachment-medium size-medium wp-post-image" alt="Kate Greenaway illustrations as bookmarks via Emmie_Norfolk on Pixabay" style="float:left; margin-right:16px; margin-bottom:16px;" decoding="async" fetchpriority="high" srcset="https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations-212x300.jpg 212w, https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations-106x150.jpg 106w, https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations.jpg 452w" sizes="(max-width: 212px) 100vw, 212px" /></div>
<p>Generic get/set functions for query string parameters that keep default values out of the URL and respect the existence of extra parameters.</p>
<p>The post <a href="https://www.rweber.net/javascript/bookmarkable-ajax-driven-pages/">Bookmarkable Ajax-Driven Pages</a> appeared first on <a href="https://www.rweber.net">rweber.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div><img width="212" height="300" src="https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations-212x300.jpg" class="attachment-medium size-medium wp-post-image" alt="Kate Greenaway illustrations as bookmarks via Emmie_Norfolk on Pixabay" style="float:left; margin-right:16px; margin-bottom:16px;" decoding="async" srcset="https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations-212x300.jpg 212w, https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations-106x150.jpg 106w, https://www.rweber.net/wp-content/uploads/2018/07/Kate-Greenaway-illustrations.jpg 452w" sizes="(max-width: 212px) 100vw, 212px" /></div><p>If someone might reasonably expect to bookmark or link others to content, I like that to be possible. With ajax-updated pages it doesn&#8217;t come for free, though. The newest addition to the <a href="https://github.com/ReveWeber/utilities">Utilities repository</a> is a little bit of get/set code for query strings to support bookmarkability.</p>
<p>The code consists of two functions, <code>parseQuery</code> and <code>updateQuery</code>. They should live inside a scope (perhaps a <a href="http://markdalgleish.com/2011/03/self-executing-anonymous-functions/">self-executing anonymous function</a>) with variables holding the default and current values of the parameters that determine the content of the page.</p>
<pre>
var default1 = "default1";
var param1;
</pre>
<p>Parsing queries is straightforward and can be done in multiple ways. This version uses a regular expression to grab everything between the parameter name with equals sign, and the next ampersand if any, provided that&#8217;s at least one character long.</p>
<pre>
function parseQuery() {
  var queryString = window.location.search.substr(1);
  // set all parameters to their default values
  param1 = default1;
  if (queryString.length > 0) {
    // if there's a query string, check for each param within it
    var val1 = queryString.match(/.*param1=([^&]+).*/i);
    if (val1) {
        param1 = val1[1];
    }
  }
}
</pre>
<p>To handle multiple parameters you&#8217;d repeat the blocks right after the comments: set all variables to the default, and then do a match and a length check for each of them within the single &#8220;if there&#8217;s a query string&#8221; check.</p>
<p>You can also split the query string into an array, but it&#8217;s a little more difficult to deal with exceptional cases like parameter names that lack values.</p>
<p>Updating the query is more complicated. I wanted my query string to consist of parameters with non-default values only, plus any parameters that don&#8217;t belong to this code. My original version simply rewrote the whole query string to consist exactly of all the parameters &#8211; default or not &#8211; and would not permit other parameters to persist, such as those that you might use to track (or deactivate) A/B tests. The reason to keep default parameters out of the query string was that one of those had a default value dependent on the date; if you bookmarked the &#8220;now&#8221; version of the page I wanted it to still be &#8220;now&#8221; when you came back a month later.</p>
<p>The answer was once again regular expressions (when is it not?).</p>
<pre>
function updateQuery() {
  var newUrl = window.location.href;
  // clean out valueless parameters to simplify ensuing matching
  newUrl = newUrl.replace(/(.*[?&])param1(&(.*))?$/, "$1$3");
  if (param1 !== default1) {
    if (newUrl.match(/[?&]param1=/)) {
      newUrl = newUrl.replace(/(.*[?&]param1=)[^&]*(.*)/, 
      '$1' + param1 + '$2');
    } else if (newUrl.indexOf('?') > 0) {
      newUrl = newUrl + '&amp;param1=' + param1;
    } else {
      newUrl = newUrl + '?param1=' + param1;
    }
  } else {
    newUrl = newUrl.replace(/(.*[?&])param1=[^&]*&?(.*)/, '$1$2');
  }

  // tidy up
  if (newUrl.match(/[?&]$/)) {
    newUrl = newUrl.slice(0, -1);
  }    
  window.history.pushState('', '', newUrl);
}
</pre>
<p>For each parameter in turn, clean out any valueless instance of it (meaning &#8220;without an equals sign&#8221;, really; if the browser allows valueless <strong>with</strong> an equals sign is will be handled in the if statements). Then, if the parameter has a non-default value, replace its value or add it as a new parameter to the string. If it is the default, remove it from the string. That is, the whole section between the two comments would be repeated for each parameter. All of this business might leave a trailing question mark or ampersand, so clean that away if needed and push the new URL into the browser history.</p>
<p>There&#8217;s a sample webpage in the repo as well, in which you can try this out, though you&#8217;ll need to update the internal links on the page to match its location on your localhost.</p>
<hr>
<p><small>Kate Greenaway illustrations as bookmarks via <a href="https://pixabay.com/en/kate-greenaway-vintage-bookmark-1519992/">Emmie_Norfolk on Pixabay</a>.</small></p>
<p>The post <a href="https://www.rweber.net/javascript/bookmarkable-ajax-driven-pages/">Bookmarkable Ajax-Driven Pages</a> appeared first on <a href="https://www.rweber.net">rweber.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rweber.net/javascript/bookmarkable-ajax-driven-pages/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">40496</post-id>	</item>
		<item>
		<title>Google Analytics: Simple RegExp for Advanced Filtration</title>
		<link>https://www.rweber.net/help-desk/google-analytics-simple-regexp-advanced-filtration/</link>
					<comments>https://www.rweber.net/help-desk/google-analytics-simple-regexp-advanced-filtration/#respond</comments>
		
		<dc:creator><![CDATA[Rebecca]]></dc:creator>
		<pubDate>Mon, 14 Aug 2017 12:00:27 +0000</pubDate>
				<category><![CDATA[Analytics]]></category>
		<category><![CDATA[Help Desk]]></category>
		<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[portfolio]]></category>
		<category><![CDATA[regex]]></category>
		<guid isPermaLink="false">http://www.rweber.net/?p=40115</guid>

					<description><![CDATA[<div><img width="300" height="271" src="https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-300x271.jpg" class="attachment-medium size-medium wp-post-image" alt="Photo by miheco on Flickr, https://www.flickr.com/photos/miheco/8043987177/" style="float:left; margin-right:16px; margin-bottom:16px;" decoding="async" srcset="https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-300x271.jpg 300w, https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-768x694.jpg 768w, https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation.jpg 1024w, https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-150x136.jpg 150w" sizes="(max-width: 300px) 100vw, 300px" /></div>
<p>A non-developer-oriented introduction to regular expressions (abbreviated RegExp or regex) for more flexible filtration in Google Analytics.</p>
<p>The post <a href="https://www.rweber.net/help-desk/google-analytics-simple-regexp-advanced-filtration/">Google Analytics: Simple RegExp for Advanced Filtration</a> appeared first on <a href="https://www.rweber.net">rweber.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div><img width="300" height="271" src="https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-300x271.jpg" class="attachment-medium size-medium wp-post-image" alt="Photo by miheco on Flickr, https://www.flickr.com/photos/miheco/8043987177/" style="float:left; margin-right:16px; margin-bottom:16px;" decoding="async" loading="lazy" srcset="https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-300x271.jpg 300w, https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-768x694.jpg 768w, https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation.jpg 1024w, https://www.rweber.net/wp-content/uploads/2017/08/Manual_coffee_preperation-150x136.jpg 150w" sizes="auto, (max-width: 300px) 100vw, 300px" /></div><p>Just a little bit of special syntax for describing patterns can greatly increase the flexibility of your filters in Google Analytics. This post is to give you that bit.</p>
<h2>What are we working with?</h2>
<p>In Google Analytics you can filter using what I&#8217;ll call the <strong>basic filtration box</strong>, that input box with the magnifying glass button above the table of data, and the <strong>advanced filtration area</strong> which opens if you click the &#8220;advanced&#8221; link next to the basic filtration box.</p>
<p>I&#8217;ll assume in this post that we&#8217;re looking at <a href="http://www.revedreams.com/">my craft blog&#8217;s</a> analytics, specifically the Behavior > Site Content > All Pages report, with the default primary dimension of Page.</p>
<p>The basic filtration box will give you generic pattern-matching: typing &#8220;crochet&#8221; will give you all URLs that have &#8220;crochet&#8221; anywhere from the beginning to the end. In the advanced area you can further specify that the URL begin with, exactly match, or end with your search string. In both locations you can use regular expressions.</p>
<p><strong>Regular expressions</strong> are a way to describe a pattern to be matched. In full generality the language is extensive and can express very complex patterns. We don&#8217;t need the full language (and GA doesn&#8217;t support all parts of it anyway), but a little RegExp goes a long way toward easily filtering to the data you&#8217;re interested in.</p>
<h2>Your first batch of syntax</h2>
<p>Regular expressions work by having a collection of <strong>reserved characters</strong>, symbols that hold special meaning in the RegExp context.</p>
<p>The most useful in GA is <code>|</code> (pipe), found above the return key along with backslash. It means &#8220;or.&#8221; For example, I did a series about embroidery on crochet where the introductory post&#8217;s slug is embroider-crochet and the later posts&#8217; slugs begin embroidery-crochet. I can capture both together with<br />
<code>embroider-crochet|embroidery-crochet</code></p>
<p>Portions of a regular expression can be enclosed in parentheses. This does nothing by itself, but can be combined with other operations. Enclosing an &#8220;or&#8221; expression in parentheses lets you make it part of a longer expression. This lets me shorten my previous filter, such as to<br />
<code>(embroidery|embroider)-crochet</code></p>
<p>Since regular expressions are their own singular option in the advanced filters, you have to use RegExp symbols to get &#8220;begins with,&#8221; &#8220;ends with,&#8221; and &#8220;exactly matches&#8221; filters (unless otherwise specified RegExps match like &#8220;contains&#8221;). Preceding your expression with <code>^</code> means &#8220;begins with&#8221; and following your expression with <code>$</code> means &#8220;ends with.&#8221; Using both gives you &#8220;exactly matches.&#8221;</p>
<p>For example, if I filtered by <code>/embroidery</code>, I would get both posts in the embroidery category (they begin with /embroidery) and the posts in the &#8220;embroidery on crochet&#8221; series (which contain /embroidery but begin /crochet). To limit myself to posts in the embroidery category I can filter with <code>^/embroidery</code>. If for some reason I wanted to filter to just the main blog page, which shows up as /, I could filter with <code>^/$</code>.</p>
<h3>Summary</h3>
<p><code>exp1|exp2</code> : matches strings matching exp1 or exp2<br />
<code>^exp1</code> : matches strings beginning with a match to exp1<br />
<code>exp1$</code> : matches strings ending with a match to exp1<br />
<code>(exp1)</code> : allows exp1 to be part of a longer pattern</p>
<h2>Special characters versus ordinary characters</h2>
<p>What if you need to use a reserved character literally? Very few reserved characters would ever appear in a URL, but they could in page titles and elsewhere.</p>
<p>There is a straightforward means to get your regular expression to interpret a character as the ordinary version and not the special RegExp version: precede it with a backslash. This is called <strong>escaping</strong> the character. For example, <code>\(</code> and <code>\)</code> get you literal parentheses.</p>
<p>Characters that need to be escaped are: <code>\ ^ $ . | ? * + ( ) [ {</code></p>
<p>I have a Related Posts plugin on the craft blog that adds query parameters to its links. If I put <code>/?related</code> into the filtration box, it wouldn&#8217;t give me what I was expecting. The ? needs to be escaped: <code>/\?related</code>.</p>
<h3>Cautionary notes</h3>
<p>In the basic filtration box, you always need to escape reserved characters since it assumes you&#8217;ve typed a regular expression by default (though GA is smart enough to interpret a lone or leading ?, say, as a literal character &#8211; meaning in our last example filtering on <code>?related</code> without the / would work just fine).</p>
<p>In the advanced filtration area, the match type drop-down must be set to “Matching RegExp” for the filter to be interpreted as a regular expression. In that case you must escape special characters, but in any other case the backslash will be interpreted literally and break your filter.</p>
<h2>A second batch of syntax</h2>
<p>What&#8217;s above may meet all of your needs. However, you may find situations in which you can&#8217;t quite get where you need to be with pipe, parens, caret and dollar sign, or where filters based on those are cumbersome.</p>
<h3>The wildcard</h3>
<p>A period in a regular expression will match any single character. For example, <code>/page/./</code> will match /page/2/ but not /page/10/. <code>/page/../</code> will match /page/10/ but not /page/2/, unless it happened to actually be /page/2//. Since I know my data doesn&#8217;t include any URLs with double slashes, I can see ultra-deep dives into content by filtering on <code>/page/../</code> to get only pages 10 and up.</p>
<h3>Repeats</h3>
<p>Instead of typing some large number of periods to match a longer string that varies, we can use characters that indicate repetition. This also allows us to match when the varying string does not always have the same length.</p>
<p>Repetition is indicated by one of three &#8220;suffix&#8221; characters: question mark, asterisk, or plus sign. They mean, respectively, 0 or 1 repeat, 0 or more repeats, 1 or more repeats. For an example:<br />
<code>A.?</code> matches A, AB, A5; does not match ABC, AB12<br />
<code>A.*</code> matches A, AB, A5, ABC, AB12<br />
<code>A.+</code> matches AB, A5, ABC, AB12; does not match A<br />
(the lists of strings matched or not matched is representative, not comprehensive)</p>
<p>Going back to the page number example, I&#8217;d like to look at engagement with pages 2 and later of all category archives. I know the URL structure will be /category/[category-name]/page/[number]/, and that the part from &#8220;page&#8221; on doesn&#8217;t exist on the first page.</p>
<p>Basically I need /category/ and /page/ with something in between, so here is my RegExp:<br />
<code>/category/.+/page/</code><br />
.* could be used interchangeably with .+ here, because there won&#8217;t be a match to category//page.</p>
<p>All three modifiers &#8211; ?, +, and * &#8211; can be used on any character, not just the period. This lets us simplify our &#8220;embroidery on crochet&#8221; filter even further. The only different between embroidery-crochet and embroider-crochet is the y, so <code>embroidery?-crochet</code> will match both. It will not match embroiders-crochet, though either <code>embroider.?-crochet</code> or <code>embroider(y|s)?-crochet</code> would match all three.</p>
<h3>Summary</h3>
<p><code>.</code> : matches any single character<br />
<code>?</code> : indicates the part of the pattern preceding it can occur 0 or 1 times<br />
<code>*</code> : indicates the part of the pattern preceding it can occur 0 or more times<br />
<code>+</code> : indicates the part of the pattern preceding it can occur 1 or more times</p>
<h2>One little side note</h2>
<p>All of my regular expressions so far have matched the case of the URLs I was trying to filter down to. By default, though, Google Analytics makes matches in a case-insensitive manner, meaning &#8220;thread&#8221; would match &#8220;Thread&#8221; and &#8220;THREAD&#8221; as well as the all-lowercase version. This generally is a helpful simplification but if capitalization is meaningful for your site, be aware you can&#8217;t filter for it simply by capitalizing in your RegExp.</p>
<h2>The full reference list</h2>
<p>Characters that need to be escaped (preceded with a backslash) to be interpreted literally:<br />
<code>\ ^ $ . | ? * + ( ) [ {</code></p>
<table>
<tr>
<td><code>|</code> </td>
<td>or </td>
<td><code>exp1|exp2</code> matches strings matching <code>exp1</code> or <code>exp2</code></td>
</tr>
<tr>
<td><code>^</code> </td>
<td>beginning </td>
<td><code>^exp1</code> matches strings beginning with a match to <code>exp1</code></td>
</tr>
<tr>
<td><code>$</code> </td>
<td>end </td>
<td><code>exp1$</code> matches strings ending with a match to <code>exp1</code></td>
</tr>
<tr>
<td><code>()</code> </td>
<td>enclosure </td>
<td><code>(exp1)</code> allows <code>exp1</code> to be part of a longer pattern</td>
</tr>
<tr>
<td><code>.</code> </td>
<td>wildcard </td>
<td><code>.</code> matches any single character</td>
</tr>
<tr>
<td><code>?</code> </td>
<td>optional </td>
<td><code>AB?</code> matches A and AB</td>
</tr>
<tr>
<td><code>*</code> </td>
<td>unlimited </td>
<td><code>AB*</code> matches A, AB, ABB, ABBB, ABBBB, &#8230;</td>
</tr>
<tr>
<td><code>+</code> </td>
<td>at least 1 </td>
<td><code>AB+</code> matches AB, ABB, ABBB, ABBBB, &#8230; but not A</td>
</tr>
</table>
<hr>
<p><small>Coffee photo by <a href="https://www.flickr.com/photos/miheco/8043987177/">miheco on Flickr</a>.</small></p>
<p>The post <a href="https://www.rweber.net/help-desk/google-analytics-simple-regexp-advanced-filtration/">Google Analytics: Simple RegExp for Advanced Filtration</a> appeared first on <a href="https://www.rweber.net">rweber.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rweber.net/help-desk/google-analytics-simple-regexp-advanced-filtration/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">40115</post-id>	</item>
		<item>
		<title>Regular Expressions</title>
		<link>https://www.rweber.net/developer-toolbox/regular-expressions/</link>
					<comments>https://www.rweber.net/developer-toolbox/regular-expressions/#respond</comments>
		
		<dc:creator><![CDATA[Rebecca]]></dc:creator>
		<pubDate>Wed, 30 Jul 2014 12:00:46 +0000</pubDate>
				<category><![CDATA[Developer Toolbox]]></category>
		<category><![CDATA[dev resources]]></category>
		<category><![CDATA[regex]]></category>
		<guid isPermaLink="false">http://www.rweber.net/?p=16382</guid>

					<description><![CDATA[<p>I am not sure how someone with my background got to this point in life without learning regular expressions. I minored in computer science in college and took a few more classes in graduate school. I took a class on models of computation that included regular languages. I ended up in the area of mathematics [&#8230;]</p>
<p>The post <a href="https://www.rweber.net/developer-toolbox/regular-expressions/">Regular Expressions</a> appeared first on <a href="https://www.rweber.net">rweber.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I am not sure how someone with my background got to this point in life without learning regular expressions. I minored in computer science in college and took a few more classes in graduate school. I took a class on models of computation that included regular languages. I ended up in the area of mathematics most strongly associated with Stephen Kleene, computability/recursion theory, and am a great admirer of his.</p>
<p>And yet, here I was, with an understanding of regular expressions generously described as &#8220;rudimentary.&#8221; I decided to fix that recently with the help of <a href="http://www.lynda.com/Regular-Expressions-tutorials/Using-Regular-Expressions/85870-2.html">Kevin Skoglund</a>, <a href="http://www.regular-expressions.info/tutorialcnt.html">Regular-Expressions.info</a>, and <a href="http://regex101.com/">Regular Expressions 101</a>. That last site lets you input an expression and text and not only shows you matches, but takes apart your expression and describes what it&#8217;s doing, and shows you the content of any captures that were made. Learning regex felt like being given a secret decoder ring, and it didn&#8217;t take long at all to learn (the Lynda course, which I recommend, is a bit over 5.5 hours, but the last two are examples).</p>
<p>I also used single pages found via Google searches and on <a href="http://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean/22944075#22944075">Stack Overflow</a>, and the <a href="http://perldoc.perl.org/perlre.html">Perl documentation</a>, though unfortunately the Perl site is nigh unnavigable. Finally, though it&#8217;s flagged with multiple issues, Wikipedia has a <a href="http://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines">comparison of regular expression engines</a> that includes which additions to ERE are and are not supported by different regex flavors.</p>
<p>I&#8217;ve typed up my notes from all these sites, and should I decide to make them pretty you&#8217;ll probably see them here.</p>
<p>The post <a href="https://www.rweber.net/developer-toolbox/regular-expressions/">Regular Expressions</a> appeared first on <a href="https://www.rweber.net">rweber.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rweber.net/developer-toolbox/regular-expressions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">16382</post-id>	</item>
	</channel>
</rss>
