Ticket #6271: smart_split.2.diff
File smart_split.2.diff, 5.6 KB (added by , 17 years ago) |
---|
-
django/utils/text.py
=== modified file 'django/utils/text.py'
178 178 ustring_re = re.compile(u"([\u0080-\uffff])") 179 179 180 180 def javascript_quote(s, quote_double_quotes=False): 181 182 181 def fix(match): 183 182 return r"\u%04x" % ord(match.group(1)) 184 183 … … 196 195 return str(ustring_re.sub(fix, s)) 197 196 javascript_quote = allow_lazy(javascript_quote, unicode) 198 197 199 smart_split_re = re.compile('("(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'|[^\\s]+)') 198 smart_split_re = re.compile(r'("(?:[^"\\]*(?:\\.[^"\\]*)*)"' 199 r"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'" 200 r'|[^\s"\']+|["\'])|\s+') 200 201 def smart_split(text): 201 202 """ 202 203 Generator that splits a string by spaces, leaving quoted phrases together. … … 205 206 quote marks. 206 207 207 208 >>> list(smart_split('This is "a person\'s" test.')) 208 ['This', 'is', '"a person\'s"', 'test.'] 209 [u'This', u'is', u'"a person\'s"', u'test.'] 210 211 Even if quoted content is found in the middle of a phrase, it is considered 212 part of the same phrase: 213 214 >>> text = '''with thelist|filter:'A B'|another:"Y Z" as var''' 215 >>> list(smart_split(text)) 216 [u'with', u'thelist|filter:\'A B\'|another:"Y Z"', u'as', u'var'] 209 217 """ 210 218 text = force_unicode(text) 219 contents = [] 211 220 for bit in smart_split_re.finditer(text): 212 bit = bit.group(0) 213 if bit[0] == '"' and bit[-1] == '"': 214 yield '"' + bit[1:-1].replace('\\"', '"').replace('\\\\', '\\') + '"' 215 elif bit[0] == "'" and bit[-1] == "'": 216 yield "'" + bit[1:-1].replace("\\'", "'").replace("\\\\", "\\") + "'" 217 else: 218 yield bit 221 content = bit.group(1) 222 if content: 223 contents.append(content) 224 elif contents: 225 yield ''.join(contents) 226 contents = [] 227 if contents: 228 yield ''.join(contents) 219 229 smart_split = allow_lazy(smart_split, unicode) 220 230 -
tests/regressiontests/utils/tests.py
=== modified file 'tests/regressiontests/utils/tests.py'
4 4 5 5 from unittest import TestCase 6 6 7 from django.utils import html, checksums 7 from django.utils import html, checksums, text 8 8 9 9 import timesince 10 10 import datastructures … … 15 15 'datastructures': datastructures, 16 16 } 17 17 18 class TestUtilsHtml(TestCase):19 18 19 class UtilsTestCase(TestCase): 20 20 21 def check_output(self, function, value, output=None): 21 22 """ 22 23 Check that function(value) equals output. If output is None, … … 26 27 output = value 27 28 self.assertEqual(function(value), output) 28 29 30 def check_generator_output(self, function, value, output=None): 31 """ 32 Check that list(function(value)) equals output. If output is None, 33 check that list(function(value)) equals value. 34 """ 35 if output is None: 36 output = value 37 self.assertEqual(list(function(value)), output) 38 39 class TestUtilsText(UtilsTestCase): 40 41 def test_smart_split(self): 42 f = text.smart_split 43 items = ( 44 # Double quotes. 45 ('arg1|filter:"1 2"', [u'arg1|filter:"1 2"']), 46 ('arg1 arg2|filter:"1" arg3', [u'arg1', u'arg2|filter:"1"', u'arg3']), 47 ('arg1 arg2|filter:"1 2" arg3', [u'arg1', u'arg2|filter:"1 2"', u'arg3']), 48 ('arg1 arg2|filter:"1 2" arg3', [u'arg1', u'arg2|filter:"1 2"', u'arg3']), 49 ('arg1 arg2|filter:"1\t2" arg3', [u'arg1', u'arg2|filter:"1\t2"', u'arg3']), 50 # With escapes. 51 ('arg1 arg2|filter:"1\\"1" arg3', [u'arg1', u'arg2|filter:"1\\"1"', u'arg3']), 52 ('arg1 arg2|filter:"1\\"\'1" arg3', [u'arg1', u'arg2|filter:"1\\"\'1"', u'arg3']), 53 # Single quotes. 54 ("arg1|filter:'1 2'", [u"arg1|filter:'1 2'"]), 55 ("arg1 arg2|filter:'1' arg3", [u'arg1', u"arg2|filter:'1'", u'arg3']), 56 ("arg1 arg2|filter:'1 2' arg3", [u'arg1', u"arg2|filter:'1 2'", u'arg3']), 57 ("arg1 arg2|filter:'1 2' arg3", [u'arg1', u"arg2|filter:'1 2'", u'arg3']), 58 ("arg1 arg2|filter:'1\t2' arg3", [u'arg1', u"arg2|filter:'1\t2'", u'arg3']), 59 # With escapes. 60 ("arg1 arg2|filter:'1\\'1' arg3", [u'arg1', u"arg2|filter:'1\\'1'", u'arg3']), 61 ("arg1 arg2|filter:'1\\'\"1' arg3", [u'arg1', u"arg2|filter:'1\\'\"1'", u'arg3']), 62 # Mixed quotes and multiple filters. 63 ("""with thelist|filter:'A B'|another:"Y Z" as var""", [u'with', u'thelist|filter:\'A B\'|another:"Y Z"', u'as', u'var']), 64 # With escapes. 65 ("""with thelist|filter:'A\\' B'|another:"Y\\" Z" as var""", [u'with', u'thelist|filter:\'A\\\' B\'|another:"Y\\" Z"', u'as', u'var']), 66 ) 67 for value, output in items: 68 self.check_generator_output(f, value, output) 69 70 71 class TestUtilsHtml(UtilsTestCase): 72 29 73 def test_escape(self): 30 74 f = html.escape 31 75 items = ( … … 123 167 for value, output in items: 124 168 self.check_output(f, value, output) 125 169 126 class TestUtilsChecksums(TestCase): 127 128 def check_output(self, function, value, output=None): 129 """ 130 Check that function(value) equals output. If output is None, 131 check that function(value) equals value. 132 """ 133 if output is None: 134 output = value 135 self.assertEqual(function(value), output) 170 class TestUtilsChecksums(UtilsTestCase): 136 171 137 172 def test_luhn(self): 138 173 f = checksums.luhn