Регулярное выражение: Сопоставьте строку (включая вложенные символы) внутри 2 символов), не захватывая символы, но не жадные

#python #regex #ply

Вопрос:

Я сделал делая язык разметки, но я теперь оптимизирован строки для него.
Я хочу, чтобы быть вложенными символов внутри строки, с моей RPLY лексер есть 3 объекта, мне нужно, чтобы внутри строк (фигурные скобки и обратные кавычки), а также не захватывая символы, такие как код регулярного выражения, которые я пробовал:

 (?:`) ([wW] )(?:`)   

Но это жадно и будет совпадать только между первой могилой, которую он видит, и последней, а также создавать не захваченные группы, которые не поддерживаются RPLY. Есть ли альтернатива этому, которая не является жадной, но допускает вложенные символы? (и, пожалуйста, никаких групп без захвата, я использую дистрибутив RPython для лексера и синтаксического анализатора PLY (RPLY), который не поддерживает группы регулярных выражений)

Если кому-то нужно больше кода, у меня есть 2 класса Python, как для лексера, так и для синтаксического анализатора.

ЛЕКСЕР

 from rply import LexerGenerator   class BMLLexer():  def __init__(self):  self.__lexer = LexerGenerator()   def __add_tokens(self):  # Statement definitions  # Note that I need both the OPEN_STATEMENT and CLOSE_STATEMENT to be allowed inside the string.  self.__lexer.add('OPEN_STATEMENT', r'{')  self.__lexer.add('CLOSE_STATEMENT', r'}')   # Basic things  # Note that RPLY's parser doesn't allow multiple groups (includes capturing and non-capturing), so the only option would be just to use functions to remove the first and last backtick from the string, or find something in regex that allows me to automatically get rid of the first and last backtick in the string.  self.__lexer.add('STRING', r'(?:`) ([wW] )(?:`) ')    # Ignore spaces  self.__lexer.ignore('s ')   def build(self):  self.__add_tokens()  return self.__lexer.build()  

синтаксический анализатор

 import re from bmls.language.parser.definitions import BMLDefinitionCapped, BMLDefinitionSingle from rply import ParserGenerator, Token  class BMLParser():  """The direct BML parser.   Raises:  SyntaxError: If given invalid syntax, the parser will throw a SyntaxError.  """  # Init parser  def __init__(self):  """Initializes the parser.  """  self.pg = ParserGenerator(  # A list of all token names accepted by the parser.  [  'OPEN_STATEMENT',  'CLOSE_STATEMENT',   'STRING',  ],   precedence= [  ('left', ['OPEN_STATEMENT']),   ('left', ['STRING']),   ('right', ['CLOSE_STATEMENT'])  ]  )     # Parsing   def parse(self):  """Parses BML content   Raises:  SyntaxError: If given invalid syntax, the parser will throw a SyntaxError.   Returns:  list: An HTML/XML formatted list of items.  """   # Multi-expression handling  @self.pg.production('main : expr')  @self.pg.production('main : main expr')  def main(p):  if len(p) == 1:  return p  else:  for x in p[1:]:  p[0].append(x)  return p[0]     # Expression handling   @self.pg.production('expr : STRING OPEN_STATEMENT main CLOSE_STATEMENT')  def definition_capped(p):  name = self.__toSTRING(p[0])  definition1 = self.__toSTRING(p[2])   comp = BMLDefinitionCapped(name, definition1)   return self.__toHTML(comp)   @self.pg.production('expr : OPEN_STATEMENT STRING CLOSE_STATEMENT')  def definition_uncapped(p):  name = self.__toSTRING(p[1])   comp = BMLDefinitionSingle(name)  return self.__toHTML(comp)     # Expression types  # This is where the string is parsed, currently using the function __removeFIrstLast. I wish to replace this with a supported expression.  @self.pg.production('expr : STRING')  def string_expr(p):  if p[0].gettokentype() == 'STRING':  return self.__removeFirstLast(self.__toSTRING(p[0]), '`', '`')     # Error handling   @self.pg.error  def error_handle(token):  raise SyntaxError('Error on Token (''   token.gettokentype()   '' , ''   token.getstr()   '')')      # Public utilities   def build(self):  return self.pg.build()     # Private utilities   def __removeFirstLast(self, tok, char, endchar):  if isinstance(tok, str):  if tok.startswith(char) and tok.endswith(endchar):  return re.sub(r'^'   char   r'|'   endchar   r'


Комментарии:

1. Вы пробовали заменить [wW] на [^`] ?

2. Я забыл включить другую часть (woops) - я не хочу полагаться на удаление первого и последнего символов из каждой строки, и я хотел бы, чтобы регулярное выражение сделало это, если это возможно. Спасибо за ответ на первую часть, хотя это было полезно и сработало.

3. И как бы я "не" соответствовал нескольким символам, таким как`, {и}, в одном и том же классе символов?

4. Вы нигде не упоминаете { и } в своем вопросе, так что теперь я действительно не знаю, в чем ваши потребности. Пожалуйста, постарайтесь сделать ваши требования более четкими, указав точно, чему, по вашему мнению, должно соответствовать регулярное выражение. (Пожалуйста, обратите внимание, что невозможно использовать следующие однополые разделители, такие как обратный тик; поскольку невозможно отличить тик закрытия от "вложенного" открытого тика. Конечно, сопоставление вложенных фигурных скобок возможно, но это невозможно сделать с помощью стандартного регулярного выражения.)

5. Я редактирую этот пост, чтобы он был более применим. Кроме того, кажется, что, поскольку у меня есть клавиатура, которая поддерживает только такой серьезный акцент ( ` ), она, похоже, работает со всем, что я пробовал. Будет ли этому жизнеспособная альтернатива? Я рассматриваю возможность использования квадратных скобок, хотя [ ([^[]] )] это и не работает для вложенных скобок. И какой вариант регулярного выражения я должен использовать, если я Python's не работает, а RPLY поддерживает только вариант Python по умолчанию?

, '', tok) else: return tok else: return tok def __toHTML(self, tok): output = '' if isinstance(tok, BMLDefinitionCapped): right = '' try: for k1 in tok.right: right = k1 except: right = tok.right output = 'lt;' tok.left 'gt;' right 'lt;/' tok.left.split(' ')[0] 'gt;' elif isinstance(tok, BMLDefinitionSingle): output = 'lt;' tok.left 'gt;' elif isinstance(tok, Token): output = tok.getstr() else: output = tok return output def __toSTRING(self, tok): if isinstance(tok, Token): return tok.getstr() else: return tok def __toINT(self, tok): if isinstance(tok, Token): return int(tok.getstr()) else: return int(tok)

Комментарии:

1. Вы пробовали заменить [wW] на [^`] ?

2. Я забыл включить другую часть (woops) — я не хочу полагаться на удаление первого и последнего символов из каждой строки, и я хотел бы, чтобы регулярное выражение сделало это, если это возможно. Спасибо за ответ на первую часть, хотя это было полезно и сработало.

3. И как бы я «не» соответствовал нескольким символам, таким как`, {и}, в одном и том же классе символов?

4. Вы нигде не упоминаете { и } в своем вопросе, так что теперь я действительно не знаю, в чем ваши потребности. Пожалуйста, постарайтесь сделать ваши требования более четкими, указав точно, чему, по вашему мнению, должно соответствовать регулярное выражение. (Пожалуйста, обратите внимание, что невозможно использовать следующие однополые разделители, такие как обратный тик; поскольку невозможно отличить тик закрытия от «вложенного» открытого тика. Конечно, сопоставление вложенных фигурных скобок возможно, но это невозможно сделать с помощью стандартного регулярного выражения.)

5. Я редактирую этот пост, чтобы он был более применим. Кроме того, кажется, что, поскольку у меня есть клавиатура, которая поддерживает только такой серьезный акцент ( ` ), она, похоже, работает со всем, что я пробовал. Будет ли этому жизнеспособная альтернатива? Я рассматриваю возможность использования квадратных скобок, хотя [ ([^[]] )] это и не работает для вложенных скобок. И какой вариант регулярного выражения я должен использовать, если я Python’s не работает, а RPLY поддерживает только вариант Python по умолчанию?