Beispiel #1
0
    def testRegexFirstGroupMatch(self):
        s = 'oXooXoooXoX'
        self.assertEqual((1, 3), libc.regex_first_group_match('(X.)', s, 0))

        # Match from position 3
        self.assertEqual((4, 6), libc.regex_first_group_match('(X.)', s, 3))

        # Match from position 3
        self.assertEqual((8, 10), libc.regex_first_group_match('(X.)', s, 6))
Beispiel #2
0
    def testRegexFirstGroupMatch(self):
        s = 'oXooXoooXoX'
        self.assertEqual((1, 3), libc.regex_first_group_match('(X.)', s, 0))

        # Match from position 3
        self.assertEqual((4, 6), libc.regex_first_group_match('(X.)', s, 3))

        # Match from position 3
        self.assertEqual((8, 10), libc.regex_first_group_match('(X.)', s, 6))

        # Syntax Error
        self.assertRaises(RuntimeError, libc.regex_first_group_match, r'*',
                          'abcd', 0)
Beispiel #3
0
    def Replace(self, s, op):
        # type: (str, suffix_op__PatSub) -> str

        regex = '(%s)' % self.regex  # make it a group

        if op.replace_mode == Id.Lit_Slash:
            try:
                return _PatSubAll(s, regex,
                                  self.replace_str)  # loop over matches
            except RuntimeError as e:
                # libc.regex_first_group_match raises RuntimeError.
                # note: MyPy doesn't know RuntimeError has e.message (and e.args)
                msg = e.message  # type: str
                e_die('Error matching regex %r: %s',
                      regex,
                      msg,
                      span_id=self.slash_spid)

        if op.replace_mode == Id.Lit_Pound:
            regex = '^' + regex
        elif op.replace_mode == Id.Lit_Percent:
            regex = regex + '$'

        m = libc.regex_first_group_match(regex, s, 0)
        #log('regex = %r, s = %r, match = %r', regex, s, m)
        if m is None:
            return s
        start, end = m
        return s[:start] + self.replace_str + s[end:]
Beispiel #4
0
    def testSpecialCharsInCharClass(self):
        CASES = [
            ("([a-z]+)", '123abc123', (3, 6)),

            # Uh what the heck, \- means the same thing as -?  It's just ignored.  At
            # least in GNU libc.

            # https://stackoverflow.com/questions/28495913/how-do-you-escape-a-hyphen-as-character-range-in-a-posix-regex
            # The <hyphen> character shall be treated as itself if it occurs first (after an initial '^', if any) or last in the list, or as an ending range point in a range expression
            ("([a\-z]+)", '123abc123', (3, 6)),

            # This is an inverted range.  TODO: Need to fix the error message.
            #("([a\-.]+)", '123abc123', None),
            ("([\\\\]+)", 'a\\b', (1, 2)),

            # Can you escape ] with \?  Yes in fnmatch, but NO here!!!
            ('([\\]])', '\\', None),
            ('([\\]])', ']', None),

            # Weird parsing!!!
            ('([\\]])', '\\]', (0, 2)),
        ]

        for pat, s, expected in CASES:
            result = libc.regex_first_group_match(pat, s, 0)
            self.assertEqual(
                expected, result,
                "FAILED: pat %r  s %r  result %s" % (pat, s, result))
Beispiel #5
0
def _AllMatchPositions(s, regex):
  """Returns a list of all (start, end) match positions of the regex against s.

  (If there are no matches, it returns the empty list.)
  """
  matches = []
  pos = 0
  n = len(s)
  while pos < n:  # needed to prevent infinite loop in (.*) case
    m = libc.regex_first_group_match(regex, s, pos)
    if m is None:
      break
    matches.append(m)
    start, end = m
    pos = end  # advance position
  return matches
Beispiel #6
0
def _AllMatchPositions(s, regex):
    """Returns a list of all (start, end) match positions of the regex against s.

  (If there are no matches, it returns the empty list.)
  """
    matches = []
    pos = 0
    while True:
        m = libc.regex_first_group_match(regex, s, pos)
        if m is None:
            break
        matches.append(m)
        start, end = m
        #log('m = %r, %r' % (start, end))
        pos = end  # advance position
    return matches
Beispiel #7
0
    def Replace(self, s, op):
        regex = '(%s)' % self.regex  # make it a group

        if op.do_all:
            return _PatSubAll(s, regex, self.replace_str)  # loop over matches

        if op.do_prefix:
            regex = '^' + regex
        elif op.do_suffix:
            regex = regex + '$'

        m = libc.regex_first_group_match(regex, s, 0)
        #log('regex = %r, s = %r, match = %r', regex, s, m)
        if m is None:
            return s
        start, end = m
        return s[:start] + self.replace_str + s[end:]
Beispiel #8
0
def PatSub(s, op, pat, replace_str):
    """Helper for ${x/pat/replace}."""
    #log('PAT %r REPLACE %r', pat, replace_str)

    regex, err = glob_.GlobToExtendedRegex(pat)
    if err:
        e_die("Can't convert glob to regex: %r", pat)

    if regex is None:  # Simple/fast path for fixed strings
        if op.do_all:
            return s.replace(pat, replace_str)
        elif op.do_prefix:
            if s.startswith(pat):
                n = len(pat)
                return replace_str + s[n:]
            else:
                return s
        elif op.do_suffix:
            if s.endswith(pat):
                n = len(pat)
                return s[:-n] + replace_str
            else:
                return s
        else:
            return s.replace(pat, replace_str, 1)  # just the first one

    else:
        regex = '(%s)' % regex  # make it a group

        if op.do_all:
            return _PatSubAll(s, regex, replace_str)  # loop over matches

        if op.do_prefix:
            regex = '^' + regex
        elif op.do_suffix:
            regex = regex + '$'

        m = libc.regex_first_group_match(regex, s, 0)
        log('regex = %r, s = %r, match = %r', regex, s, m)
        if m is None:
            return s
        start, end = m
        return s[:start] + replace_str + s[end:]
Beispiel #9
0
  def Replace(self, s, op):
    regex = '(%s)' % self.regex  # make it a group

    if op.replace_mode == Id.Lit_Slash:
      try:
        return _PatSubAll(s, regex, self.replace_str)  # loop over matches
      except RuntimeError as e:
        e_die('Error matching regex %r: %s', regex, e, span_id=self.slash_spid)

    if op.replace_mode == Id.Lit_Pound:
      regex = '^' + regex
    elif op.replace_mode == Id.Lit_Percent:
      regex = regex + '$'

    m = libc.regex_first_group_match(regex, s, 0)
    #log('regex = %r, s = %r, match = %r', regex, s, m)
    if m is None:
      return s
    start, end = m
    return s[:start] + self.replace_str + s[end:]
Beispiel #10
0
 def testRegexFirstGroupMatchError(self):
     # Helping to debug issue #291
     s = ''
     if 0:
         libc.regex_first_group_match("(['+-'])", s, 6)