fork download
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import re
  4.  
  5. def lreplace(s, old, new):
  6. """Return a copy of string `s` with leading occurrences of
  7. substring `old` replaced by `new`.
  8.  
  9. >>> lreplace('abcabcdefabc', 'abc', 'X')
  10. 'XXdefabc'
  11. >>> lreplace('_abc', 'abc', 'X')
  12. '_abc'
  13. >>> print lreplace('☃☃_[☃]_☃', '☃', 'SM')
  14. SMSM_[☃]_☃
  15. """
  16. return re.sub(r'^(?:%s)+' % re.escape(old),
  17. lambda m: new * (m.end() // len(old)),
  18. s)
  19.  
  20. def replaceLeadingString(string, old, new = ''):
  21. # http://stackoverflow.com/q/4649997
  22. n = 0
  23. o = 0
  24. s = len(old)
  25.  
  26. while string.startswith(old, o):
  27. n += 1
  28. o += s
  29.  
  30. return new * n + string[o:]
  31.  
  32. #from profilestats import profile
  33. #@profile
  34. def test(n):
  35. for _ in xrange(n):
  36. old, new = 'префикс', 'abc'
  37. for s in [old*2 +'остаток',
  38. 'no'+old,
  39. old,
  40. old*2,
  41. new+new,
  42. 'xx\n'+old,
  43. ]:
  44. args = s, old, new
  45. assert lreplace(*args) == replaceLeadingString(*args)
  46.  
  47. if __name__=="__main__":
  48. import cProfile
  49. cProfile.run('test(10**4)')
  50.  
  51.  
Success #stdin #stdout 2.27s 6724KB
stdin
Standard input is empty
stdout
         860332 function calls (860325 primitive calls) in 2.255 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.255    2.255 <string>:1(<module>)
    30000    0.057    0.000    0.083    0.000 prog.py:17(<lambda>)
    60000    0.184    0.000    0.269    0.000 prog.py:20(replaceLeadingString)
        1    0.171    0.171    2.255    2.255 prog.py:34(test)
    60000    0.224    0.000    1.815    0.000 prog.py:5(lreplace)
    60000    0.112    0.000    0.567    0.000 re.py:144(sub)
    60000    0.890    0.000    1.024    0.000 re.py:206(escape)
    60000    0.108    0.000    0.163    0.000 re.py:229(_compile)
        1    0.000    0.000    0.000    0.000 sre_compile.py:360(_simple)
        1    0.000    0.000    0.000    0.000 sre_compile.py:367(_compile_info)
      3/1    0.000    0.000    0.000    0.000 sre_compile.py:38(_compile)
        2    0.000    0.000    0.000    0.000 sre_compile.py:480(isstring)
        1    0.000    0.000    0.000    0.000 sre_compile.py:486(_code)
        1    0.000    0.000    0.001    0.001 sre_compile.py:501(compile)
        4    0.000    0.000    0.000    0.000 sre_parse.py:132(__len__)
       20    0.000    0.000    0.000    0.000 sre_parse.py:136(__getitem__)
        1    0.000    0.000    0.000    0.000 sre_parse.py:140(__setitem__)
       16    0.000    0.000    0.000    0.000 sre_parse.py:144(append)
      4/2    0.000    0.000    0.000    0.000 sre_parse.py:146(getwidth)
        1    0.000    0.000    0.000    0.000 sre_parse.py:184(__init__)
       23    0.000    0.000    0.000    0.000 sre_parse.py:188(__next)
        8    0.000    0.000    0.000    0.000 sre_parse.py:201(match)
       19    0.000    0.000    0.000    0.000 sre_parse.py:207(get)
       14    0.000    0.000    0.000    0.000 sre_parse.py:263(_escape)
      2/1    0.000    0.000    0.000    0.000 sre_parse.py:307(_parse_sub)
      2/1    0.000    0.000    0.000    0.000 sre_parse.py:385(_parse)
        1    0.000    0.000    0.000    0.000 sre_parse.py:669(parse)
        1    0.000    0.000    0.000    0.000 sre_parse.py:73(__init__)
        3    0.000    0.000    0.000    0.000 sre_parse.py:96(__init__)
        1    0.000    0.000    0.000    0.000 {_sre.compile}
    30000    0.015    0.000    0.015    0.000 {built-in method end}
    60000    0.210    0.000    0.293    0.000 {built-in method sub}
       23    0.000    0.000    0.000    0.000 {isinstance}
150069/150068    0.055    0.000    0.055    0.000 {len}
       59    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    60028    0.053    0.000    0.053    0.000 {method 'get' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}
    60000    0.060    0.000    0.060    0.000 {method 'join' of 'str' objects}
   110000    0.064    0.000    0.064    0.000 {method 'startswith' of 'str' objects}
        6    0.000    0.000    0.000    0.000 {min}
       14    0.000    0.000    0.000    0.000 {ord}
    60000    0.051    0.000    0.051    0.000 {range}