# Copyright 2017 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. """Regular expression helpers.""" import re def _CreateIdentifierRegex(parts): assert parts if parts[0]: # Allow word boundary or a _ prefix. prefix_pattern = r'\b_?' else: # Allow word boundary, _, or a case transition. prefix_pattern = r'(?:\b|(?<=_)|(?<=[a-z])(?=[A-Z]))' parts = parts[1:] assert parts if parts[-1]: # Allow word boundary, trailing _, or single trailing digit. suffix_pattern = r'\d?_?\b' else: # Allow word boundary, _, or a case transition. suffix_pattern = r'(?:\b|(?=_|\d)|(?<=[a-z])(?=[A-Z]))' parts = parts[:-1] assert parts shouty_pattern = '_'.join(a.upper() for a in parts) snake_pattern = '_'.join(a.lower() for a in parts) camel_remainder = parts[0][1:] for token in parts[1:]: camel_remainder += token.title() first_letter = parts[0][0] prefixed_pattern = '[a-z]' + first_letter.upper() + camel_remainder camel_pattern = '[%s%s]%s' % (first_letter.lower(), first_letter.upper(), camel_remainder) middle_patterns = '|'.join( (shouty_pattern, snake_pattern, prefixed_pattern, camel_pattern)) return r'(?:%s(?:%s)%s)' % (prefix_pattern, middle_patterns, suffix_pattern) def ExpandRegexIdentifierPlaceholder(pattern): """Expands {{identifier}} within a given regular expression. Returns |pattern|, with the addition that {{some_name}} is expanded to match: SomeName, kSomeName, SOME_NAME, etc. To match part of a name, use {{_some_name_}}. This will additionally match: kPrefixSomeNameSuffix, PREFIX_SOME_NAME_SUFFIX, etc. Note: SymbolGroup.Where* methods call this function already, so there is generally no need to call it directly. """ return re.sub(r'\{\{(.*?)\}\}', lambda m: _CreateIdentifierRegex(m.group(1).split('_')), pattern)