【问题标题】:How to exclude the bracketed characters in a Python f-string using regex?如何使用正则表达式排除 Python f 字符串中的括号字符?
【发布时间】:2021-02-14 13:55:55
【问题描述】:

最近,我一直在 Python 3.7.6 中创建一个编辑器(使用 tkinter),我创建了以下语法来突出显示单引号、双引号和三引号,但我想排除 f- 大括号内的所有字符字符串,我尝试使用[^\{(.*)\}] 作为否定集,但后来意识到它不起作用。我尝试在互联网上搜索,但所有这些都不适合我的正则表达式。

这是代码的正则表达式部分:

def regex_groups(self, name, alternates):
    return "(?P<%s>" % name + "|".join(alternates) + ")"

stringprefix = r"(\bB|b|br|Br|bR|BR|rb|rB|Rb|RB|r|u|R|U|f|F|fr|Fr|fR|FR|rf|rF|Rf|RF)?"
sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?"
dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?'
sqqqstring = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
dqqqstring = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?'
string = self.regex_groups("STRING", [sqqqstring, dqqqstring, sqstring, dqstring])

我尝试将stringprefix 分解为两个字符串r"(f|F|fr|Fr|fR|FR|rf|rF|Rf|RF)?"r"(B|b|br|Br|bR|BR|rb|rB|Rb|RB|r|u|R|U)?",然后将它们分别与sqstring, dqstring, sq3string and dq3string 一起使用,但没有成功。

这是正则表达式测试的一部分:

请帮帮我!

任何帮助表示赞赏! :)

【问题讨论】:

  • 你对第三个带花括号的字符串有什么期望?
  • 开/关字符对不规则。您无法使用正则表达式准确匹配它们。
  • 我的期望是它应该突出显示 f'This is an { ,把它们放在中间(在这种情况下是 f_string 然后是 }'
  • @MisterMiyagi 当我尝试使用正则表达式从任何不带引号的大括号中排除文本时,它可以工作,但带引号则不能
  • 您希望f"This is an {{plain string}}"f"This is a set: { {1, 2, 3}}" 得到什么结果?

标签: python regex f-string


【解决方案1】:

我不知道正则表达式是否适合这里。您可以只使用标准库中的 tokenize 模块来解析和标记您的 Python 源代码。根据每个令牌的类型,您可以选择不同的颜色。例如:

import tokenize
from io import BytesIO

src = """
def foo(bar):
    print(bar, "hi there")
"""

tokens = tokenize.tokenize(BytesIO(src.encode("utf-8")).readline)

openers = ("class", "def", "for", "while", "if", "try", "except")

for token in tokens:
    color = ""
    line = token.start[0]
    start = token.start[1]
    end = token.end[1]
    if token.exact_type == tokenize.NAME and token.string in openers:
        color = "orange"
    elif token.exact_type == tokenize.NAME:
        color = "blue"
    elif token.exact_type == tokenize.STRING:
        color = "green"

    if color:
        print(f"token '{token.string}' (line: {line}, col: {start} - {end}) should be {color}")

输出:

token 'def' (line: 2, col: 0 - 3) should be orange
token 'foo' (line: 2, col: 4 - 7) should be blue
token 'bar' (line: 2, col: 8 - 11) should be blue
token 'print' (line: 3, col: 4 - 9) should be blue
token 'bar' (line: 3, col: 10 - 13) should be blue
token '"hi there"' (line: 3, col: 15 - 25) should be green
>>> 

将标记类型映射到颜色的查找表(字典)比一大块 if 语句更合适,但你明白了。

【讨论】:

  • 你是对的,但是编辑器已经制作好了,它就像内置的 IDLE 一样工作,但有更多的功能(比如自动完成括号,自动完成像 if __name__ == '__main__' 这样的语句、def __init__(self): 等)。因此,也许重写整个事情对于这个来说可能不是一个好主意,但仍然感谢您的回答。我可以在另一个编辑器中使用它(比如我制作的编辑器的第二个版本或类似的东西)。但目前我对 f-string 功能的唯一希望是正则表达式(如果可能)。
猜你喜欢
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多