diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 0db77f1..3ffd071 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -14,6 +14,8 @@ from django.utils.itercompat import groupby
 from django.utils.safestring import mark_safe
 
 register = Library()
+# Regex for token keyword arguments
+kwarg_re = re.compile(r"(?:(\w+)=)?(.+)")
 
 class AutoEscapeControlNode(Node):
     """Implements the actions of the autoescape tag."""
@@ -1071,12 +1073,9 @@ def templatetag(parser, token):
     return TemplateTagNode(tag)
 templatetag = register.tag(templatetag)
 
-# Regex for URL arguments including filters
-url_arg_re = re.compile(
-    r"(?:(%(name)s)=)?(%(value)s(?:\|%(name)s(?::%(value)s)?)*)" % {
-        'name':'\w+',
-        'value':'''(?:(?:'[^']*')|(?:"[^"]*")|(?:[\w\.-]+))'''},
-    re.VERBOSE)
+# Backwards compatibility check which will fail against for old comma
+# separated arguments in the url tag.
+url_backwards_re = re.compile(r'''(('[^']*'|"[^"]*"|[^,]+)=?)+$''')
 
 def url(parser, token):
     """
@@ -1085,7 +1084,11 @@ def url(parser, token):
     This is a way to define links that aren't tied to a particular URL
     configuration::
 
-        {% url path.to.some_view arg1,arg2,name1=value1 %}
+        {% url path.to.some_view arg1 arg2 %}
+        
+        or
+        
+        {% url path.to.some_view name1=value1 name2=value2 %}
 
     The first argument is a path to a view. It can be an absolute python path
     or just ``app_name.view_name`` without the project name if the view is
@@ -1117,27 +1120,28 @@ def url(parser, token):
     args = []
     kwargs = {}
     asvar = None
-
-    if len(bits) > 2:
-        bits = iter(bits[2:])
+    bits = bits[2:]
+    if len(bits) >= 2 and bits[-2] == 'as':
+        asvar = bits[-1]
+        bits = bits[:-2]
+
+    # Backwards compatibility: {% url urlname arg1,arg2 %} or
+    # {% url urlname arg1,arg2 as foo %} cases.
+    if bits:
+        old_args = ''.join(bits)
+        if not url_backwards_re.match(old_args):
+            bits = old_args.split(",")
+
+    if len(bits):
         for bit in bits:
-            if bit == 'as':
-                asvar = bits.next()
-                break
+            match = kwarg_re.match(bit)
+            if not match:
+                raise TemplateSyntaxError("Malformed arguments to url tag")
+            name, value = match.groups()
+            if name:
+                kwargs[name] = parser.compile_filter(value)
             else:
-                end = 0
-                for i, match in enumerate(url_arg_re.finditer(bit)):
-                    if (i == 0 and match.start() != 0) or \
-                          (i > 0 and (bit[end:match.start()] != ',')):
-                        raise TemplateSyntaxError("Malformed arguments to url tag")
-                    end = match.end()
-                    name, value = match.group(1), match.group(2)
-                    if name:
-                        kwargs[name] = parser.compile_filter(value)
-                    else:
-                        args.append(parser.compile_filter(value))
-                if end != len(bit):
-                    raise TemplateSyntaxError("Malformed arguments to url tag")
+                args.append(parser.compile_filter(value))
 
     return URLNode(viewname, args, kwargs, asvar)
 url = register.tag(url)
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index aabacc5..f015370 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -891,7 +891,7 @@ Returns an absolute URL (i.e., a URL without the domain name) matching a given
 view function and optional parameters. This is a way to output links without
 violating the DRY principle by having to hard-code URLs in your templates::
 
-    {% url path.to.some_view arg1,arg2,name1=value1 %}
+    {% url path.to.some_view arg1 arg2 name1=value1 %}
 
 The first argument is a path to a view function in the format
 ``package.package.module.function``. Additional arguments are optional and
@@ -935,7 +935,7 @@ If you'd like to retrieve a URL without displaying it, you can use a slightly
 different call::
 
 
-    {% url path.to.view arg, arg2 as the_url %}
+    {% url path.to.view arg arg2 as the_url %}
 
     <a href="{{ the_url }}">I'm linking to {{ the_url }}</a>
 
@@ -957,6 +957,12 @@ This will follow the normal :ref:`namespaced URL resolution strategy
 <topics-http-reversing-url-namespaces>`, including using any hints provided
 by the context as to the current application.
 
+.. versionchanged:: 1.2
+
+For backwards compatibility, the ``{% url %}`` tag supports the old syntax
+from previous Django versions of comma separating the arguments. The previous
+syntax does not support commas as part of string literals in the arguments.
+
 .. templatetag:: widthratio
 
 widthratio
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 307fecc..2ae3146 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -1020,9 +1020,15 @@ class Templates(unittest.TestCase):
 
             ### URL TAG ########################################################
             # Successes
+            'legacyurl02': ('{% url regressiontests.templates.views.client_action id=client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
+            'legacyurl02a': ('{% url regressiontests.templates.views.client_action client.id,"update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
+            'legacyurl10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'),
+            'legacyurl13': ('{% url regressiontests.templates.views.client_action id=client.id, action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
+            'legacyurl14': ('{% url regressiontests.templates.views.client_action client.id, arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
+
             'url01': ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'),
-            'url02': ('{% url regressiontests.templates.views.client_action id=client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
-            'url02a': ('{% url regressiontests.templates.views.client_action client.id,"update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
+            'url02': ('{% url regressiontests.templates.views.client_action id=client.id action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
+            'url02a': ('{% url regressiontests.templates.views.client_action client.id "update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
             'url03': ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'),
             'url04': ('{% url named.client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'),
             'url05': (u'{% url метка_оператора v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
@@ -1031,9 +1037,11 @@ class Templates(unittest.TestCase):
             'url08': (u'{% url метка_оператора v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
             'url09': (u'{% url метка_оператора_2 tag=v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
             'url10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'),
-            'url11': ('{% url regressiontests.templates.views.client_action id=client.id,action="==" %}', {'client': {'id': 1}}, '/url_tag/client/1/==/'),
-            'url12': ('{% url regressiontests.templates.views.client_action id=client.id,action="," %}', {'client': {'id': 1}}, '/url_tag/client/1/,/'),
-            'url12': ('{% url regressiontests.templates.views.client_action id=client.id,action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
+            'url11': ('{% url regressiontests.templates.views.client_action id=client.id action="==" %}', {'client': {'id': 1}}, '/url_tag/client/1/==/'),
+            'url12': ('{% url regressiontests.templates.views.client_action id=client.id action="," %}', {'client': {'id': 1}}, '/url_tag/client/1/,/'),
+            'url13': ('{% url regressiontests.templates.views.client_action id=client.id action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
+            'url14': ('{% url regressiontests.templates.views.client_action client.id arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'),
+            'url15': ('{% url regressiontests.templates.views.client_action 12 "test" %}', {}, '/url_tag/client/12/test/'),
 
             # Failures
             'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
