python-3.x - 让用户使用字符串创建自定义格式
问题描述
我希望用户能够在其中创建自定义格式,QtWidgets.QPlainTextEdit()
它将格式化字符串并将结果拆分为另一个QtWidgets.QPlainTextEdit()
.
例如:
movie = {
"Title":"The Shawshank Redemption",
"Year":"1994",
"Rated":"R",
"Released":"14 Oct 1994",
"Runtime":"142 min",
"Genre":"Drama",
"Director":"Frank Darabont",
"Writer":"Stephen King (short story \"Rita Hayworth and Shawshank Redemption\"),Frank Darabont (screenplay)",
"Actors":"Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler",
"Plot":"Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.",
"Language":"English",
"Country":"USA",
"Awards":"Nominated for 7 Oscars. Another 21 wins & 36 nominations.",
"Poster":"https://m.media-amazon.com/images/M/MV5BMDFkYTc0MGEtZmNhMC00ZDIzLWFmNTEtODM1ZmRlYWMwMWFmXkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_SX300.jpg",
"Ratings": [
{
"Source":"Internet Movie Database",
"Value":"9.3/10"
},
{
"Source":"Rotten Tomatoes",
"Value":"91%"
},
{
"Source":"Metacritic",
"Value":"80/100"
}
],
"Metascore":"80",
"imdbRating":"9.3",
"imdbVotes":"2,367,380",
"imdbID":"tt0111161",
"Type":"movie",
"DVD":"15 Aug 2008",
"BoxOffice":"$28,699,976",
"Production":"Columbia Pictures, Castle Rock Entertainment",
"Website":"N/A"
}
custom_format = '[ {Title} | ⌚ {Runtime} | ⭐ {Genre} | {Released} | {Rated} ]'.format(Title=movie['Title'], Runtime=movie['Runtime'], Genre=movie['Genre'],Released=movie['Released'],Rated=movie['Rated'])
print(custom_format)
上面的这段代码很容易打印[ The Shawshank Redemption | ⌚ 142 min | ⭐ Drama | 14 Oct 1994 | R ]
.
但是,如果我将此代码更改为:
custom_format = '[ {Title} | ⌚ {Runtime} | ⭐ {Genre} | {Released} | {Rated} ]'.format(Title=movie['Title'], Runtime=movie['Runtime'], Genre=movie['Genre'],Released=movie['Released'],Rated=movie['Rated'])
至:
custom_format = "'[ {Title} | ⌚ {Runtime} | ⭐ {Genre} | {Released} | {Rated} ]'.format(Title=movie['Title'], Runtime=movie['Runtime'], Genre=movie['Genre'],Released=movie['Released'],Rated=movie['Rated'])"
请注意,整个内容都包含在“”中。因此它是一个字符串。现在这样做不会打印出我想要的格式。我将它包装在 "" 中的原因是,当我将原始文件添加custom_format
到 aQtWidgets.QPlainTextEdit()
时,它会将其转换为稍后不会格式化的字符串。
所以我最初的想法是,用户在QtWidgets.QPlainTextEdit()
. 然后我复制该格式,打开一个包含电影 json 变量的新窗口,并将该格式粘贴到另一个QtWidgets.QPlainTextEdit()
希望显示其格式正确的地方。
对此的任何帮助将不胜感激。
附加信息:
用户在QtWidgets.QPlainTextEdit()
.
然后用户点击Test Format
应该显示[ The Shawshank Redemption | ⌚ 142 min | ⭐ Drama | 14 Oct 1994 | R ]
但它显示
解决方案
尝试使用完整格式命令需要一个eval()
,这通常被认为不仅是不好的做法,而且是一个严重的安全问题,尤其是当输入参数完全由用户设置时。
由于字段是已知的,我认为提供整个格式行没有什么意义,最好解析格式字符串以查找关键字,然后使用关键字查找来创建输出。
class Formatter(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.formatBase = QtWidgets.QPlainTextEdit(
'[ {Title} | ⌚ {Runtime} | ⭐ {Genre} | {Released} | {Rated} ]')
self.formatOutput = QtWidgets.QPlainTextEdit()
layout.addWidget(self.formatBase)
layout.addWidget(self.formatOutput)
self.formatBase.textChanged.connect(self.processFormat)
self.processFormat()
def processFormat(self):
format_str = self.formatBase.toPlainText()
# escape double braces
clean = re.sub('{{', '', re.sub('}}', '', format_str))
# capture keyword arguments
tokens = re.split(r'\{(.*?)\}', clean)
keywords = tokens[1::2]
try:
# build the dictionary with given arguments, unrecognized keywords
# are just printed back in the {key} form, in order let the
# user know that the key wasn't valid;
values = {k:movie.get(k, '{{{}}}'.format(k)) for k in keywords}
self.formatOutput.setPlainText(format_str.format(**values))
except (ValueError, KeyError):
# exception for unmatching braces
pass
推荐阅读
- sql - 将列内包含 JSON 数组的行扩展为多行
- database - PowerBI 连接到 Azure Cosmosdb
- java - 如何使用 if 语句在构造函数中声明最终字符串?
- android - Android TextView Gravity BOTTOM 意外行为
- swagger - 在 Swagger 2 中是否可以默认处于试用模式?
- python-3.x - 如何在 Plotly 甘特图中指定其他颜色?
- typescript - 打字稿数组随机变为未定义
- jquery - pen.js:205 Uncaught TypeError: $(...).addclass is not a function
- c# - 将列表传递给多值转换器
- python - 是否可以在 Azure Functions (python) 中使用 BlockBlobService?