普通文本  |  68行  |  2.07 KB

#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import re

def quote(input_str, specials, escape='\\'):
  """Returns a quoted version of |str|, where every character in the
  iterable |specials| (usually a set or a string) and the escape
  character |escape| is replaced by the original character preceded by
  the escape character."""

  assert len(escape) == 1

  # Since escape is used in replacement pattern context, so we need to
  # ensure that it stays a simple literal and cannot affect the \1
  # that will follow it.
  if escape == '\\':
    escape = '\\\\'
  if len(specials) > 0:
    return re.sub(r'(' + r'|'.join(specials)+r'|'+escape + r')',
                  escape + r'\1', input_str)
  return re.sub(r'(' + escape + r')', escape + r'\1', input_str)


def unquote(input_str, specials, escape='\\'):
  """Splits the input string |input_str| where special characters in
  the input |specials| are, if not quoted by |escape|, used as
  delimiters to split the string.  The returned value is a list of
  strings of alternating non-specials and specials used to break the
  string. The list will always begin with a possibly empty string of
  non-specials, but may end with either specials or non-specials."""

  assert len(escape) == 1

  out = []
  cur_out = []
  cur_special = False
  lit_next = False
  for c in input_str:
    if cur_special:
      lit_next = (c == escape)
      if c not in specials or lit_next:
        cur_special = False
        out.append(''.join(cur_out))
        if not lit_next:
          cur_out = [c]
        else:
          cur_out = []
      else:
        cur_out.append(c)
    else:
      if lit_next:
        cur_out.append(c)
        lit_next = False
      else:
        lit_next = c == escape
        if c not in specials:
          if not lit_next:
            cur_out.append(c)
        else:
          out.append(''.join(cur_out))
          cur_out = [c]
          cur_special = True
  out.append(''.join(cur_out))
  return out