如何使用 AppleScript 从 JSON 文件中获取值?
How to get values from JSON file using AppleScript?
关于这个问题,
如何从如下所示的 JSON 文件中获取值,
["AA-BB-CC-MAKE-SAME.json","SS-ED-SIXSIX-TENSE.json","FF-EE-EE-EE-WW.json","ZS-WE-AS-FOUR-MINE.json","DD-RF-LATERS-LATER.json","FG-ER-DC-ED-FG.json"]
在 MAC 中使用 AppleScript OS?
这是Hackoo,
提供的Windows中的部分VBScript代码
strJson = http.responseText
Result = Extract(strJson,"(\x22(.*)\x22)")
Arr = Split(Result,",")
For each Item in Arr
wscript.echo Item
Next
'******************************************
Function Extract(Data,Pattern)
Dim oRE,oMatches,Match,Line
set oRE = New RegExp
oRE.IgnoreCase = True
oRE.Global = True
oRE.Pattern = Pattern
set oMatches = oRE.Execute(Data)
If not isEmpty(oMatches) then
For Each Match in oMatches
Line = Line & Trim(Match.Value) & vbCrlf
Next
Extract = Line
End if
End Function
'******************************************
在 MAC OS AppleScript 中,我只需要将 JSON 文件的值获取到单个字符串值数组的代码。上面显示的 VBScript 示例是 JSON 文件内容的样子。
How to get the values from JSON file that looks like this,
["AA-BB-CC-MAKE-SAME.json","SS-ED-SIXSIX-TENSE.json","FF-EE-EE-EE-WW.json","ZS-WE-AS-FOUR-MINE.json","DD-RF-LATERS-LATER.json","FG-ER-DC-ED-FG.json"]
如果您的意思是您所写的,并且 JSON 文件的内容是单个数组中六个字符串的列表,在一行中格式化,最简单的方法是将其视为文本,trim 打开和关闭方括号,然后在每次出现 ,
时分隔其字段。最后,每个单独的文本项也可以有周围的引号 trimmed。
检查 VBScript,它看起来使用了一个非常相似的过程,尽管使用了正则表达式,AppleScript 没有提供正则表达式,但在这种简单情况下并不是特别必要。
假设上面的 JSON 数组存储在桌面上名为“myfile.json”的文件中。那么:
set home to the path to home folder
set f to the POSIX path of home & "Desktop/myfile.json"
set JSONstr to read POSIX file f
# Trim square brackets
set JSONstr to text 2 thru -2 of JSONstr
# Delimit text fields using comma
set the text item delimiters to ","
set Arr to the text items of JSONstr
# Trim quotes of each item in Arr
repeat with a in Arr
set contents of a to text 2 thru -2 of a
end repeat
# The final array
Arr
I only need the code to get the values of the JSON file to a single array of string values. The above shown example above the VBScript is the how JSON file contents looks like.
变量 Arr
现在包含字符串值数组(在 AppleScript 中称为 lists)。您可以像这样访问其中的特定项目:
item 2 of Arr --> "SS-ED-SIXSIX-TENSE.json"
更通用的解决方案
我决定在 AppleScript 中包含一种更高级的方法来处理 JSON,部分原因是我最近一直在做很多 JSON 处理,而且这一切都是新鲜的我的事件视界;还要证明,使用 AppleScriptObjC,不仅可以解析非常复杂的 JSON 数据,而且非常简单。
我认为您在这种特定情况下不需要它,但它可能会在未来的某些情况下派上用场。
该脚本分为三个部分:它开始导入赋予 AppleScript 额外权力的相关 Objective-C 框架;然后,我定义了实际的处理程序本身,称为 JSONtoRecord
,我将在下面进行描述。最后,是脚本的底部,您可以在其中输入代码并随心所欲地使用它:
use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------
property ca : a reference to current application
property NSData : a reference to ca's NSData
property NSDictionary : a reference to ca's NSDictionary
property NSJSONSerialization : a reference to ca's NSJSONSerialization
property NSString : a reference to ca's NSString
property NSUTF8StringEncoding : a reference to 4
--------------------------------------------------------------------------------
on JSONtoRecord from fp
local fp
set JSONdata to NSData's dataWithContentsOfFile:fp
set [x, E] to (NSJSONSerialization's ¬
JSONObjectWithData:JSONdata ¬
options:0 ¬
|error|:(reference))
if E ≠ missing value then error E
tell x to if its isKindOfClass:NSDictionary then ¬
return it as record
x as list
end JSONtoRecord
--------------------------------------------------------------------------------
###YOUR CODE BELOW HERE
#
#
set home to the path to home folder
set f to the POSIX path of home & "Desktop/myfile.json"
JSONtoRecord from f
--> {"AA-BB-CC-MAKE-SAME.json", "SS-ED-SIXSIX-TENSE.json", ¬
--> "FF-EE-EE-EE-WW.json", "ZS-WE-AS-FOUR-MINE.json", ¬
--> "DD-RF-LATERS-LATER.json", "FG-ER-DC-ED-FG.json"}
在脚本的底部,我调用了 JSONtoRecord
处理程序,将 myfile.json
的位置传递给它。此处理程序的好处之一是,无论文件是在一行上格式化还是在多行上格式化都无关紧要。它还可以处理复杂的嵌套 JSON 数组。
在这些情况下,它 returns 是原生 AppleScript record
对象,所有 JSON 变量都存储为记录中的 属性 值。然后访问变量变得非常简单。
这实际上正是一些人已经提到的 JSON Helper
应用程序在幕后所做的事情。
一个标准(除了包含有效 JSON 数据的 JSON 文件外)是文件的路径是完整写入的 posix 路径,例如/Users/CK/Desktop/myfile.json
,不是 ~/Desktop/myfile.json
,甚至更糟,Macintosh HD:Users:CK:Desktop:myfile.json
。
简短回答: 不幸的是,AppleScript 不提供解析 JSON 的内置功能,这类似于 JavaScript 的 JSON.parse()
方法。
以下是几个解决方案:
- 解决方案一:需要安装第三方插件,不一定可行。
- 解决方案2:不需要安装任何第三方插件,而是使用macOS内置的tools/features作为标准。
解决方案 1:
如果您有能力在您的用户系统上安装第三方插件,那么您可以安装 JSON Helper for AppleScript (正如@user3439894 在评论中所建议的那样).
然后在您的 AppleScript 中使用它,如下所示:
set srcJson to read POSIX file (POSIX path of (path to home folder) & "Desktop/foobar.json")
tell application "JSON Helper" to set myList to read JSON from srcJson
解释:
在第 1 行,我们读取 .json
文件的内容并将其分配给名为 srcJson
的变量。
注意您需要根据需要更改路径部分(即Desktop/foobar.json
)。
在第 2 行 我们使用 JSON Helper 插件解析内容。这会将源 JSON 数组的每个项目分配给新的 AppleScript list
。生成的 AppleScript list
被分配给名为 myList
.
的变量
解决方案 2:
通过使用 macOS 内置的标准工具,您还可以通过 AppleScript 执行以下操作。这假设您的 JSON 文件是 valid 并且仅包含一个数组:
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set myList to text items of (do shell script "tr ''\\n\\r'' ' ' <~/Desktop/foobar.json | sed 's/^ *\[ *\"//; s/ *\" *\] *$//; s/\" *, *\"/,/g;'")
set AppleScript's text item delimiters to TID
注意:您需要根据需要更改路径部分(即~/Desktop/foobar.json
)。
此外,如果您的 .json
文件名包含 space(s),您需要使用 \
对它们进行转义。例如~/Desktop/foo\ bar.json
解释:
在 第 1 行 AppleScript 的当前 text item delimiters 被分配给名为 TID
.
[=191 的变量=]
在第 2 行 AppleScript's text item delimiters
设置为逗号 - 这有助于从源 JSON 中提取每个单独的值数组并将每个值分配给新的 AppleScript list
.
在第3行一个shell脚本通过do shell script
命令执行,执行以下操作:
通过读取~/Desktop/foobar.json
的部分读取源.json
文件的内容。此路径当前假定文件名为 foobar.json
并位于您的 Desktop
文件夹中 (您需要将此路径更改为实际文件所在的位置)。
foobar.json
的内容被重定向,(注意文件路径前的 <
),到 tr
(即读取的部分:tr ''\\n\\r'' ' '
).此翻译将用 space 字符替换源 .json
数组内容中可能存在的任何换行符。这确保 foobar.json
的内容转换为一行。
注意:JSON 数组可以在每个项目之间包含换行符并且仍然有效,因此尽管您问题中给出的示例 JSON 出现在一行 - 这不是此解决方案的要求,因为它也可以处理多行。
然后将一行文本通过管道传输到 sed
的 s
command 进行进一步处理(即读取的部分:| sed 's/^ *\[ *\"//; s/ *\" *\] *$//; s/\" *, *\"/,/g;'
)。
The syntax of the s
command is 's/regexp/replacement/flags'
.
让我们分解每个 s
命令以进一步了解发生了什么:
s/^ *\[ *\"//
删除左方括号 [
,其前面或后面可能有零个或多个 space 字符,以及从字符串开头开始的以下双引号(即第一次出现)。
s/ *\" *\] *$//
删除右方括号 ]
,其前面或后面可能有零个或多个 space 字符,以及字符串末尾的前面的双引号(即最后一次出现)。
s/\" *, *\"/,/g
替换单个逗号,(前面可以有零个或多个 space,and/or后跟零个或多个 spaces) 和一个逗号。
第 3 行 的开头部分是这样的; set myList to text items of ...
利用 text items
将字符串读入 AppleScript list
,使用逗号作为分隔符来确定 list
的每个项目。结果数组分配给名为 myList
.
的变量
在第4行 AppleScript's text item delimiters
恢复到原来的值。
为源 JSON 文件路径使用变量。
如果你想使用一个变量作为源 .json
文件的文件路径,那么你可以这样做:
set srcFilePath to quoted form of (POSIX path of (path to home folder) & "Desktop/foobar.json")
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set myList to text items of (do shell script "tr ''\\n\\r'' ' ' <" & srcFilePath & " | sed 's/^ *\[ *\"//; s/ *\" *\] *$//; s/\" *, *\"/,/g;'")
set AppleScript's text item delimiters to TID
注意这与第一个例子非常相似。显着差异是:
- 在第一行,我们将文件路径分配给名为
srcFilePath
的变量。
- 在
do shell script
中我们引用 srcFilePath
变量。
关于 JSON 转义特殊字符的补充说明: 解决方案 2 保留任何 JSON escaped special characters 可能出现在 source JSON 数组的值中。但是,解决方案 1 将解释它们。
注意事项 解决方案 2 在源 JSON 数组中的项目包含逗号时产生意外结果,因为逗号是用作 text item delimiters
.
关于这个问题,
如何从如下所示的 JSON 文件中获取值,
["AA-BB-CC-MAKE-SAME.json","SS-ED-SIXSIX-TENSE.json","FF-EE-EE-EE-WW.json","ZS-WE-AS-FOUR-MINE.json","DD-RF-LATERS-LATER.json","FG-ER-DC-ED-FG.json"]
在 MAC 中使用 AppleScript OS?
这是Hackoo,
提供的Windows中的部分VBScript代码strJson = http.responseText
Result = Extract(strJson,"(\x22(.*)\x22)")
Arr = Split(Result,",")
For each Item in Arr
wscript.echo Item
Next
'******************************************
Function Extract(Data,Pattern)
Dim oRE,oMatches,Match,Line
set oRE = New RegExp
oRE.IgnoreCase = True
oRE.Global = True
oRE.Pattern = Pattern
set oMatches = oRE.Execute(Data)
If not isEmpty(oMatches) then
For Each Match in oMatches
Line = Line & Trim(Match.Value) & vbCrlf
Next
Extract = Line
End if
End Function
'******************************************
在 MAC OS AppleScript 中,我只需要将 JSON 文件的值获取到单个字符串值数组的代码。上面显示的 VBScript 示例是 JSON 文件内容的样子。
How to get the values from JSON file that looks like this,
["AA-BB-CC-MAKE-SAME.json","SS-ED-SIXSIX-TENSE.json","FF-EE-EE-EE-WW.json","ZS-WE-AS-FOUR-MINE.json","DD-RF-LATERS-LATER.json","FG-ER-DC-ED-FG.json"]
如果您的意思是您所写的,并且 JSON 文件的内容是单个数组中六个字符串的列表,在一行中格式化,最简单的方法是将其视为文本,trim 打开和关闭方括号,然后在每次出现 ,
时分隔其字段。最后,每个单独的文本项也可以有周围的引号 trimmed。
检查 VBScript,它看起来使用了一个非常相似的过程,尽管使用了正则表达式,AppleScript 没有提供正则表达式,但在这种简单情况下并不是特别必要。
假设上面的 JSON 数组存储在桌面上名为“myfile.json”的文件中。那么:
set home to the path to home folder
set f to the POSIX path of home & "Desktop/myfile.json"
set JSONstr to read POSIX file f
# Trim square brackets
set JSONstr to text 2 thru -2 of JSONstr
# Delimit text fields using comma
set the text item delimiters to ","
set Arr to the text items of JSONstr
# Trim quotes of each item in Arr
repeat with a in Arr
set contents of a to text 2 thru -2 of a
end repeat
# The final array
Arr
I only need the code to get the values of the JSON file to a single array of string values. The above shown example above the VBScript is the how JSON file contents looks like.
变量 Arr
现在包含字符串值数组(在 AppleScript 中称为 lists)。您可以像这样访问其中的特定项目:
item 2 of Arr --> "SS-ED-SIXSIX-TENSE.json"
更通用的解决方案
我决定在 AppleScript 中包含一种更高级的方法来处理 JSON,部分原因是我最近一直在做很多 JSON 处理,而且这一切都是新鲜的我的事件视界;还要证明,使用 AppleScriptObjC,不仅可以解析非常复杂的 JSON 数据,而且非常简单。
我认为您在这种特定情况下不需要它,但它可能会在未来的某些情况下派上用场。
该脚本分为三个部分:它开始导入赋予 AppleScript 额外权力的相关 Objective-C 框架;然后,我定义了实际的处理程序本身,称为 JSONtoRecord
,我将在下面进行描述。最后,是脚本的底部,您可以在其中输入代码并随心所欲地使用它:
use framework "Foundation"
use scripting additions
--------------------------------------------------------------------------------
property ca : a reference to current application
property NSData : a reference to ca's NSData
property NSDictionary : a reference to ca's NSDictionary
property NSJSONSerialization : a reference to ca's NSJSONSerialization
property NSString : a reference to ca's NSString
property NSUTF8StringEncoding : a reference to 4
--------------------------------------------------------------------------------
on JSONtoRecord from fp
local fp
set JSONdata to NSData's dataWithContentsOfFile:fp
set [x, E] to (NSJSONSerialization's ¬
JSONObjectWithData:JSONdata ¬
options:0 ¬
|error|:(reference))
if E ≠ missing value then error E
tell x to if its isKindOfClass:NSDictionary then ¬
return it as record
x as list
end JSONtoRecord
--------------------------------------------------------------------------------
###YOUR CODE BELOW HERE
#
#
set home to the path to home folder
set f to the POSIX path of home & "Desktop/myfile.json"
JSONtoRecord from f
--> {"AA-BB-CC-MAKE-SAME.json", "SS-ED-SIXSIX-TENSE.json", ¬
--> "FF-EE-EE-EE-WW.json", "ZS-WE-AS-FOUR-MINE.json", ¬
--> "DD-RF-LATERS-LATER.json", "FG-ER-DC-ED-FG.json"}
在脚本的底部,我调用了 JSONtoRecord
处理程序,将 myfile.json
的位置传递给它。此处理程序的好处之一是,无论文件是在一行上格式化还是在多行上格式化都无关紧要。它还可以处理复杂的嵌套 JSON 数组。
在这些情况下,它 returns 是原生 AppleScript record
对象,所有 JSON 变量都存储为记录中的 属性 值。然后访问变量变得非常简单。
这实际上正是一些人已经提到的 JSON Helper
应用程序在幕后所做的事情。
一个标准(除了包含有效 JSON 数据的 JSON 文件外)是文件的路径是完整写入的 posix 路径,例如/Users/CK/Desktop/myfile.json
,不是 ~/Desktop/myfile.json
,甚至更糟,Macintosh HD:Users:CK:Desktop:myfile.json
。
简短回答: 不幸的是,AppleScript 不提供解析 JSON 的内置功能,这类似于 JavaScript 的 JSON.parse()
方法。
以下是几个解决方案:
- 解决方案一:需要安装第三方插件,不一定可行。
- 解决方案2:不需要安装任何第三方插件,而是使用macOS内置的tools/features作为标准。
解决方案 1:
如果您有能力在您的用户系统上安装第三方插件,那么您可以安装 JSON Helper for AppleScript (正如@user3439894 在评论中所建议的那样).
然后在您的 AppleScript 中使用它,如下所示:
set srcJson to read POSIX file (POSIX path of (path to home folder) & "Desktop/foobar.json")
tell application "JSON Helper" to set myList to read JSON from srcJson
解释:
在第 1 行,我们读取
.json
文件的内容并将其分配给名为srcJson
的变量。注意您需要根据需要更改路径部分(即
Desktop/foobar.json
)。在第 2 行 我们使用 JSON Helper 插件解析内容。这会将源 JSON 数组的每个项目分配给新的 AppleScript
list
。生成的 AppleScriptlist
被分配给名为myList
. 的变量
解决方案 2:
通过使用 macOS 内置的标准工具,您还可以通过 AppleScript 执行以下操作。这假设您的 JSON 文件是 valid 并且仅包含一个数组:
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set myList to text items of (do shell script "tr ''\\n\\r'' ' ' <~/Desktop/foobar.json | sed 's/^ *\[ *\"//; s/ *\" *\] *$//; s/\" *, *\"/,/g;'")
set AppleScript's text item delimiters to TID
注意:您需要根据需要更改路径部分(即~/Desktop/foobar.json
)。
此外,如果您的 .json
文件名包含 space(s),您需要使用 \
对它们进行转义。例如~/Desktop/foo\ bar.json
解释:
在 第 1 行 AppleScript 的当前 text item delimiters 被分配给名为
[=191 的变量=]TID
.在第 2 行
AppleScript's text item delimiters
设置为逗号 - 这有助于从源 JSON 中提取每个单独的值数组并将每个值分配给新的 AppleScriptlist
.在第3行一个shell脚本通过
do shell script
命令执行,执行以下操作:通过读取
~/Desktop/foobar.json
的部分读取源.json
文件的内容。此路径当前假定文件名为foobar.json
并位于您的Desktop
文件夹中 (您需要将此路径更改为实际文件所在的位置)。foobar.json
的内容被重定向,(注意文件路径前的<
),到tr
(即读取的部分:tr ''\\n\\r'' ' '
).此翻译将用 space 字符替换源.json
数组内容中可能存在的任何换行符。这确保foobar.json
的内容转换为一行。注意:JSON 数组可以在每个项目之间包含换行符并且仍然有效,因此尽管您问题中给出的示例 JSON 出现在一行 - 这不是此解决方案的要求,因为它也可以处理多行。
然后将一行文本通过管道传输到
sed
的s
command 进行进一步处理(即读取的部分:| sed 's/^ *\[ *\"//; s/ *\" *\] *$//; s/\" *, *\"/,/g;'
)。The syntax of the
s
command is's/regexp/replacement/flags'
.让我们分解每个
s
命令以进一步了解发生了什么:s/^ *\[ *\"//
删除左方括号[
,其前面或后面可能有零个或多个 space 字符,以及从字符串开头开始的以下双引号(即第一次出现)。s/ *\" *\] *$//
删除右方括号]
,其前面或后面可能有零个或多个 space 字符,以及字符串末尾的前面的双引号(即最后一次出现)。s/\" *, *\"/,/g
替换单个逗号,(前面可以有零个或多个 space,and/or后跟零个或多个 spaces) 和一个逗号。
第 3 行 的开头部分是这样的;
set myList to text items of ...
利用text items
将字符串读入 AppleScriptlist
,使用逗号作为分隔符来确定list
的每个项目。结果数组分配给名为myList
. 的变量
在第4行
AppleScript's text item delimiters
恢复到原来的值。
为源 JSON 文件路径使用变量。
如果你想使用一个变量作为源 .json
文件的文件路径,那么你可以这样做:
set srcFilePath to quoted form of (POSIX path of (path to home folder) & "Desktop/foobar.json")
set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set myList to text items of (do shell script "tr ''\\n\\r'' ' ' <" & srcFilePath & " | sed 's/^ *\[ *\"//; s/ *\" *\] *$//; s/\" *, *\"/,/g;'")
set AppleScript's text item delimiters to TID
注意这与第一个例子非常相似。显着差异是:
- 在第一行,我们将文件路径分配给名为
srcFilePath
的变量。 - 在
do shell script
中我们引用srcFilePath
变量。
关于 JSON 转义特殊字符的补充说明: 解决方案 2 保留任何 JSON escaped special characters 可能出现在 source JSON 数组的值中。但是,解决方案 1 将解释它们。
注意事项 解决方案 2 在源 JSON 数组中的项目包含逗号时产生意外结果,因为逗号是用作 text item delimiters
.