Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(revision 6454)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java	(revision 6455)
@@ -64,5 +64,5 @@
     public static enum Op {
         EQ, NEQ, GREATER_OR_EQUAL, GREATER, LESS_OR_EQUAL, LESS,
-        REGEX, ONE_OF, BEGINS_WITH, ENDS_WITH, CONTAINS;
+        REGEX, NREGEX, ONE_OF, BEGINS_WITH, ENDS_WITH, CONTAINS;
 
         public boolean eval(String testString, String prototypeString) {
@@ -75,7 +75,8 @@
                 return !equal(testString, prototypeString);
             case REGEX:
+            case NREGEX:
                 Pattern p = Pattern.compile(prototypeString);
                 Matcher m = p.matcher(testString);
-                return m.find();
+                return REGEX.equals(this) ? m.find() : !m.find();
             case ONE_OF:
                 String[] parts = testString.split(";");
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 6454)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 6455)
@@ -368,4 +368,7 @@
             <EQUAL> <TILDE> { op=Condition.Op.REGEX; } s() val=regex()
         |
+        LOOKAHEAD(2)
+            <EXCLAMATION> <TILDE> { op=Condition.Op.NREGEX; } s() val=regex()
+        |
             (
                     <EXCLAMATION> <EQUAL> { op=Condition.Op.NEQ; }
Index: trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/AllMapCSSTests.groovy
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/AllMapCSSTests.groovy	(revision 6454)
+++ trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/AllMapCSSTests.groovy	(revision 6455)
@@ -12,4 +12,5 @@
     ParsingLinkSelectorTest.class,
     KeyConditionTest.class,
+    MapCSSParserTest.class,
     ChildOrParentSelectorTest
 ])
Index: trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy	(revision 6455)
+++ trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy	(revision 6455)
@@ -0,0 +1,60 @@
+package org.openstreetmap.josm.gui.mappaint.mapcss
+
+import org.junit.Test
+import org.openstreetmap.josm.Main
+import org.openstreetmap.josm.data.Preferences
+import org.openstreetmap.josm.data.osm.OsmPrimitive
+import org.openstreetmap.josm.data.osm.Way
+import org.openstreetmap.josm.gui.mappaint.Environment
+import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser
+
+class MapCSSParserTest {
+
+    protected static OsmPrimitive getPrimitive(String key, String value) {
+        def w = new Way()
+        w.put(key, value)
+        return w
+    }
+
+    @Test
+    public void testEqualCondition() throws Exception {
+        def condition = (Condition.KeyValueCondition) new MapCSSParser(new StringReader("[surface=paved]")).condition(Condition.Context.PRIMITIVE)
+        assert condition instanceof Condition.KeyValueCondition
+        assert Condition.Op.EQ.equals(condition.op)
+        assert "surface".equals(condition.k)
+        assert "paved".equals(condition.v)
+        Main.pref = new Preferences()
+        assert condition.applies(new Environment().withPrimitive(getPrimitive("surface", "paved")))
+        assert !condition.applies(new Environment().withPrimitive(getPrimitive("surface", "unpaved")))
+    }
+
+    @Test
+    public void testNotEqualCondition() throws Exception {
+        def condition = (Condition.KeyValueCondition) new MapCSSParser(new StringReader("[surface!=paved]")).condition(Condition.Context.PRIMITIVE)
+        assert condition instanceof Condition.KeyValueCondition
+        assert Condition.Op.NEQ.equals(condition.op)
+        Main.pref = new Preferences()
+        assert !condition.applies(new Environment().withPrimitive(getPrimitive("surface", "paved")))
+        assert condition.applies(new Environment().withPrimitive(getPrimitive("surface", "unpaved")))
+    }
+
+    @Test
+    public void testRegexCondition() throws Exception {
+        def condition = (Condition.KeyValueCondition) new MapCSSParser(new StringReader("[surface=~/paved|unpaved/]")).condition(Condition.Context.PRIMITIVE)
+        assert condition instanceof Condition.KeyValueCondition
+        assert Condition.Op.REGEX.equals(condition.op)
+        Main.pref = new Preferences()
+        assert condition.applies(new Environment().withPrimitive(getPrimitive("surface", "unpaved")))
+        assert !condition.applies(new Environment().withPrimitive(getPrimitive("surface", "grass")))
+    }
+
+    @Test
+    public void testNegatedRegexCondition() throws Exception {
+        def condition = (Condition.KeyValueCondition) new MapCSSParser(new StringReader("[surface!~/paved|unpaved/]")).condition(Condition.Context.PRIMITIVE)
+        assert condition instanceof Condition.KeyValueCondition
+        assert Condition.Op.NREGEX.equals(condition.op)
+        Main.pref = new Preferences()
+        assert !condition.applies(new Environment().withPrimitive(getPrimitive("surface", "unpaved")))
+        assert condition.applies(new Environment().withPrimitive(getPrimitive("surface", "grass")))
+    }
+}
