diff --git a/HandsomeSoup.cabal b/HandsomeSoup.cabal
--- a/HandsomeSoup.cabal
+++ b/HandsomeSoup.cabal
@@ -7,7 +7,7 @@
 -- The package version. See the Haskell package versioning policy
 -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
 -- standards guiding when and how versions should be incremented.
-Version:             0.2
+Version:             0.3
 
 -- A short (one-line) description of the package.
 Synopsis:            Work with HTML more easily in HXT
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,12 +1,12 @@
 # HandsomeSoup
 
-Current Status: Usable but untested (tests coming soon! See todo list).
+Current Status: Usable. Please file bugs!
 
 HandsomeSoup is the library I wish I had when I started parsing HTML in Haskell.
 
 It is built on top of [HXT](http://www.fh-wedel.de/~si/HXmlToolbox/) and adds a few functions that make is easier to work with HTML.
 
-Most importantly, it adds CSS selectors to HXT. The goal of HandsomeSoup is to be a complete CSS2 parser for HXT (it is very close to this right now).
+Most importantly, it adds CSS selectors to HXT. The goal of HandsomeSoup is to be a complete CSS2 selector parser for HXT.
 
 ## Install
 
@@ -30,7 +30,7 @@
 ### Or a local page using `parseHtml`
 
     contents <- readFile [filename]
-    doc <- parseHtml contents
+    let doc = parseHtml contents
 
 ### Easily extract elements using `css`
 
@@ -41,10 +41,12 @@
     doc <<< css "a#link1"
     doc <<< css "a.foo"
     doc <<< css "p > a"
+    doc <<< css "p strong"
     doc <<< css "#container h1"
     doc <<< css "img[width]"
     doc <<< css "img[width=400]"
     doc <<< css "a[class~=bar]"
+    doc <<< css "a:first-child"
 
 ### Easily get attributes using `(!)`
 
diff --git a/Text/CSS/Parser.hs b/Text/CSS/Parser.hs
--- a/Text/CSS/Parser.hs
+++ b/Text/CSS/Parser.hs
@@ -4,14 +4,20 @@
 import qualified Data.Functor.Identity as I
 import Data.List
 import Text.CSS.Utils
-
 -- if no tag name was given, sName will be set to '*'
 -- attrs are (attr name, attr value).
 -- if attr value is the empty string, we just check to
 -- make sure that the element has that attribute.
+--
 -- if the attr value is prefixed with a '~', we treat
 -- that attribute as a list of words separated by a space
 -- and make sure that at least one of those words matches.
+-- 
+-- if the attr value is prefixed with a `|`, the value must
+-- be exactly val or start with val immediately followed by a '-'.
+-- This is primarily intended to allow language subcode matches.
+-- Example: [lang|="en"] matches "en", "en-US", etc.
+-- From: http://www.w3.org/TR/CSS2/selector.html.
 data Selector = Selector { sName :: String, sAttrs :: [(String,String)], spseudoSelectores :: [String] } | Space | ChildOf | FollowedBy deriving (Show)
 
 -- pretty printers for debugging
@@ -52,12 +58,16 @@
 -- | selects attributes, like @ [id] @ (element must have id) or @ [id=foo] @ (element must have id foo).
 attributeSelector :: ParsecT [Char] u I.Identity ([Char], [Char])
 attributeSelector = do
-      contents <- between (char '[') (char ']') (many1 (alphaNum <|> oneOf "~="))
+      _contents <- between (char '[') (char ']') (many1 (alphaNum <|> oneOf "|~=\"'"))
+      -- remove quotes
+      let contents = filter (\c -> c /= '"' && c /= '\'') _contents
       if "~=" `isInfixOf` contents 
           then return $ (\(a, b) -> (a, '~':b)) $ splitOn "~=" contents
-          else if '=' `elem` contents
-               then return $ splitOn "=" contents
-               else return (contents, "")
+          else if "|=" `isInfixOf` contents 
+              then return $ (\(a, b) -> (a, '|':b)) $ splitOn "|=" contents
+              else if '=' `elem` contents
+                   then return $ splitOn "=" contents
+                   else return (contents, "")
 
 -- | selector for everything after the type except pseudoSelectores
 secondarySelector = many1 (classSelector <|> idSelector <|> attributeSelector)
diff --git a/Text/HandsomeSoup.hs b/Text/HandsomeSoup.hs
--- a/Text/HandsomeSoup.hs
+++ b/Text/HandsomeSoup.hs
@@ -67,7 +67,14 @@
         makeAttrs [] = this
         makeAttr (name, "") = hasAttr name
         makeAttr (name, '~':value) = hasAttrValue name (elem value . words)
+        makeAttr (name, '|':value) = hasAttrValue name (headMatch value)
         makeAttr (name, value) = hasAttrValue name (==value)
         makePseudos (p:pseudos) = foldl (\acc pseudo -> acc >>> makePseudo pseudo) (makePseudo p) pseudos
         makePseudos [] = id
         makePseudo "first-child" = take 1
+
+-- | Used internally to match attribute selectors like @ [att|=val] @.
+-- From: http://www.w3.org/TR/CSS2/selector.html
+-- "Represents an element with the att attribute, its value either being exactly "val" or beginning with "val" immediately followed by '-'".
+headMatch value attrValue = value == attrValue || value `isPrefixOf` attrValue
+    where first = head . words $ attrValue
