Common Ruby Regex Patterns

Filed Under (Ruby) by adam on 27-07-2008

Tagged Under : , ,

My earlier (rather lame) post on Ruby Regex’s (Regular Expressions) is getting some Google love, so I thought I would supplement it with some more useful information.

If you are searching for Ruby Regex help, my guess is you are looking for…

Validating an email address with a Ruby Regex

Something simple like this next one will get you started.

irb(main):023:0> “me@adamloving.com”.match /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i

For a much more complete email address ruby regex, try:

#
# RFC822 Email Address Regex
# --------------------------
#
# Originally written by Cal Henderson
# c.f. http://iamcal.com/publish/articles/php/parsing_email/
#
# Translated to Ruby by Tim Fletcher, with changes suggested by Dan Kubb.
#
# Licensed under a Creative Commons Attribution-ShareAlike 2.5 License
# http://creativecommons.org/licenses/by-sa/2.5/
#
module RFC822
  EmailAddress = begin
    qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
    dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
    atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
      '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
    quoted_pair = '\\x5c[\\x00-\\x7f]'
    domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
    quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
    domain_ref = atom
    sub_domain = "(?:#{domain_ref}|#{domain_literal})"
    word = "(?:#{atom}|#{quoted_string})"
    domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
    local_part = "#{word}(?:\\x2e#{word})*"
    addr_spec = "#{local_part}\\x40#{domain}"
    pattern = /\A#{addr_spec}\z/
  end
end

Find URLs using a Regular Expression in Ruby

Here is a simple URL matching regular expression.

irb(main):028:0> "http://www.adamloving.com/".match /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix

Changes to FriendFeed Python Library for use with App Engine

Filed Under (Python) by adam on 22-07-2008

UPDATE: you should definitely go with Benjamin Golub’s Python FriendFeed library for App Engine (fftogo). It is cleaner than mine and includes some undocumented API calls (like fetch_entry).

I had to make some minor modifications to the FriendFeed python library to get it to work with Google App Engine. App Engine does not support out urllib2, and has its own urlfetch library.

Here is the cut and paste-able code (see also pastie, I’m having trouble with code formatting in Wordpress)

# original (FriendFeed.py 0.9)
def _fetch(self, uri, post_args, **url_args):
    url_args["format"] = "json"
    args = urllib.urlencode(url_args)
    url = "http://friendfeed.com" + uri + "?" + args
    if post_args is not None:
        request = urllib2.Request(url, urllib.urlencode(post_args))
    else:
        request = urllib2.Request(url)
    if self.auth_nickname and self.auth_key:
        pair = "%s:%s" % (self.auth_nickname, self.auth_key)
        token = base64.b64encode(pair)
        request.add_header("Authorization", "Basic %s" % token)
    stream = urllib2.urlopen(request)
    data = stream.read()
    stream.close()
    return parse_json(data)
# modified
def _fetch(self, uri, post_args, **url_args):
    url_args["format"] = "json"
    args = urllib.urlencode(url_args)
    url = "http://friendfeed.com" + uri + "?" + args
    headers = {}
    if post_args is not None:
        post_data = urllib.urlencode(post_args)
        method = "POST"
        headers={'Content-Type': 'application/x-www-form-urlencoded'}
    else:
        post_data = None
        method = "GET"

    if self.auth_nickname and self.auth_key:
        pair = "%s:%s" % (self.auth_nickname, self.auth_key)
        token = base64.b64encode(pair)
        headers["Authorization"] = "Basic %s" % token

    result = urlfetch.fetch(url=url, payload=post_data, method=method, headers=headers)
    data = result.content

    self.result = result
    self.feed_json = data

    return parse_json(data)

Ruby boolean operator (or ruby parsing) bug

Filed Under (Ruby) by adam on 09-07-2008

Tagged Under : ,

This has bitten me a couple times in the last few days. The Ruby “or” (or equals) operator appears to have a bug where, when used in an assignment, the first value is assigned rather than the results of the entire expression.

irb(main):001:0> x = false || true
=> true
irb(main):002:0> x
=> true
irb(main):003:0> z = false or true
=> true
irb(main):004:0> z
=> false

ruby version: ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.10.1]

I would expect z to be true in that last example.

Zemanta Pixie

Translating c# to Ruby, Python, Java and Javascript

Filed Under (Programming) by adam on 21-06-2008

Tagged Under : , , ,

I created a Google spreadsheet to help me learn common phrases in Ruby and Python. This is an overly-ambitious project that I’ll probably never finish (I’ll have the function names learned faster than I update the spreadsheet). Anyone out there want to help? Add a comment below and I’ll ad you as a contributor to the spreadsheet.

Getting started with Python on Mac OS X Tiger

Filed Under (Programming) by adam on 19-06-2008

Tagged Under : ,

I upgraded Python 2.3 to Python 2.5 on my Macbook, and changed some symbolic links so that 2.5 is the default version when run from the command line. In backwards order, here is what I did.

Python is pre-installed on Mac OS X Tiger, but what version am I running and where is it?

Open a terminal window (bash command shell) and type “python”

$ python
Python 2.5.2 (r252:60911, Jun  1 2008, 16:53:35)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin

I’m running 2.5 now, but I wasn’t earlier. Ok, where is Python installed?

$ which python
/usr/bin/python

Is that the real location? No, it is a symbolic link.

$ ls -l /usr/bin/python*
lrwxr-xr-x   1 root  wheel      9 Jun 19 13:13 /usr/bin/python -> python2.5
lrwxr-xr-x   1 root  wheel     72 Oct 14  2006 /usr/bin/python2.3 -> ../../System/Library/Frameworks/Python.framework/Versions/2.3/bin/python
lrwxr-xr-x   1 root  wheel     82 Jun 19 13:15 /usr/bin/python2.5 -> /opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/bin/python2.5

As you can see, I changed “python” to point to python2.5. Previously it pointed to python2.3.

Where can I get Python 2.5 for Mac OS X Tiger? I used macports.

$ port install python25

this will put it in /opt/local/var/macports

$ port location python25
Port python25 2.5.2_2+darwin_8 is installed as an image in:
/opt/local/var/macports/software/python25/2.5.2_2+darwin_8

Python Path and Module Basics

Filed Under (Programming) by adam on 19-06-2008

Tagged Under : , ,

I’m getting started with Python and Google App Engine. One of the first things I had to figure out was how Python handles paths and module names.
You can see what paths python is looking on with this command sequence:

 

$ python
['', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python25.zip', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python2.5', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python2.5/plat-darwin', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python2.5/plat-mac', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python2.5/plat-mac/lib-scriptpackages', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python2.5/lib-tk', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python2.5/lib-dynload', '/opt/local/var/macports/software/python25/2.5.2_2+darwin_8/opt/local/lib/python2.5/site-packages']
Python 2.5.2 (r252:60911, Jun  1 2008, 16:53:35)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
>>> exit()

 

Inside a python script Modules are included with this syntax:
from google.appengine.ext.bulkload import constants
All that means is that python is going to look on the paths above for /google/appengine/ext/bulkload/constants.py
In my case, the script I was trying to run sets up the paths for a secondary main script with some code like this:

 

EXTRA_PATHS = [
DIR_PATH,
os.path.join(GOOGLE_PATH, 'lib', 'django'),
os.path.join(GOOGLE_PATH, 'lib', 'webob'),
os.path.join(GOOGLE_PATH, 'lib', 'yaml', 'lib'),
]
if __name__ == '__main__':
sys.path = EXTRA_PATHS + sys.path
script_path = os.path.join(DIR_PATH, BULKLOAD_CLIENT_PATH)
execfile(script_path, globals())

 

So, you can see here that sys.path is assignable and retained when calling other scripts.
I also learned that you can set the $PYTHONPATH environment variable to a list of paths, just like the normal $PATH variable. However, unlike Windows, you have “export” the environment variable.

 

$ PYTHONPATH=$PYTHONPATH:/include/this:/and/this
export $PYTHONPATH

 

The export command takes the local shell variable and makes it visible as a global variable (in this case to Python).

Downloading a Remote Image and Saving it with AttachmentFu

Filed Under (Ruby) by admin on 07-06-2008

Tagged Under : ,

I had some issues this week figuring out how to save a file using AttachmentFu. It is well suited to handling files uploaded via a Web form, but when you load a file in programmatically, it isn't obvious what object properties need to be set. Here is what I ended up with.

response = HttpClient.default.request(url)

mugshot = Mugshot.new

temp_file_name = mugshot.write_to_temp_file(response.body)

mugshot.temp_path = temp_file_name

mugshot.content_type = "image/#{content_type}"

mugshot.filename = "imported_photo.#{content_type}"

if person.mugshot

# remove existing database records of files for this person

thumbnail = Mugshot.find_by_parent_id(person.mugshot.id)

thumbnail.destroy

person.mugshot.destroy

end

mugshot.person = person

mugshot.save

Q: How do you stub a method call for a rails unit test such that it returns a…

Filed Under (Ruby) by admin on 07-06-2008

Tagged Under : ,

Q: How do you stub a method call for a rails unit test such that it returns a different value the second time it is called? A:  stubs(:foo).returns(1,2) returns 1 the first call, 2 the second, etc.

How to perform a MySQL update from one table to another

Filed Under (Databases and SQL) by admin on 07-06-2008

Tagged Under : , ,

The MS SQL syntax is different from the MySQL syntax (MS SQL allows you to do a join).

UPDATE updatefrom p, updateto pp

SET pp.last_name = p.last_name

WHERE pp.visid = p.id

Rails rake command to run a single unit test

Filed Under (Ruby) by admin on 06-06-2008

Tagged Under : , ,

Q: What is the rake command to run a single rails unit test? A: There is none, use ruby test/unit/my_test.rb