删除尾随空格时 Applescript 代码中断
Applescript code breaking when removing trailing spaces
从字符串中删除最后一个字符应该是一段简单的代码,但似乎无缘无故地中断了(无论如何对我来说)。
我正在尝试创建一个简单的脚本来解决同事在文件名和扩展名周围有多余空格时出现的 OneDrive 文件同步问题。
离开很长时间后回到 AppleScript,似乎忘记了一切,只需要了解为什么应该简单的东西似乎让我感到困惑...对我温柔点。
on stripSpaces(thisText)
local newText
local pos
local tempText
set newText to thisText
set tempText to ""
repeat while tempText ≠ newText
set tempText to newText
--remove spaces before extension name
set pos to the offset of ". " in newText
if pos > 0 then
set newText to ((characters 1 thru pos of newText) as text) & (characters (pos + 2) thru end of newText) as text
end if
--remove spaces before extension
set pos to the offset of " ." in newText
if pos > 0 then
set newText to ((characters 1 thru (pos - 1) of newText) as text) & (characters (pos + 1) thru end of newText) as text
end if
--remove leading spaces
if character 1 of newText = " " then
set newText to characters 2 thru end of newText as text
end if
---BROKEN SECTION
--remove trailing spaces
if (last character of newText) = " " then
set newText to (characters 1 thru (end of newText) - 1) as text
end if
end repeat
return newText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
错误 "Can’t get end of \" 水疗中心。完成。文本文件 \”。”从“spa.nish.txt”的最后一个插入点开始的数字 -1728
使用 text 1 thru -1 of newText
获取文本范围要容易得多,其中 -1 是最后一个字符。这也避免了所有 as text
强制转换。
on stripSpaces(thisText)
local newText
local pos
local tempText
set newText to thisText
set tempText to ""
repeat while tempText ≠ newText
set tempText to newText
--remove spaces before extension name
set pos to the offset of ". " in newText
if pos > 0 then
set newText to text 1 thru pos of newText & text (pos + 2) thru -1 of newText
end if
--remove spaces before extension
set pos to the offset of " ." in newText
if pos > 0 then
set newText to text 1 thru (pos - 1) of newText & text (pos + 1) thru -1 of newText
end if
--remove leading spaces
if first character of newText = space then
set newText to text 2 thru -1 of newText
end if
--remove trailing spaces
if last character of newText = space then
set newText to text 1 thru -2 of newText
end if
end repeat
return newText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
借助 AppleScriptObjC 的一点帮助,整个处理程序可以减少到两行
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
on stripSpaces(thisText)
set nsText to current application's NSString's stringWithString:thisText
return (nsText's stringByReplacingOccurrencesOfString:" " withString:"") as text
end stripSpaces
log stripSpaces(" spa . nish . txt ")
您问题的直接答案是您不应在此上下文中使用 'end',而应使用“-1”表示最后一个字符,“-2”表示倒数第二个字符等等。结果最终会是这样的:
on stripSpaces(thisText)
local newText
local pos
local tempText
set newText to thisText
set tempText to ""
repeat while tempText ≠ newText
set tempText to newText
--remove spaces before extension name
set pos to the offset of ". " in newText
if pos > 0 then
set newText to ((characters 1 thru pos of newText) as text) & (characters (pos + 2) thru -1 of newText) as text
end if
--remove spaces before extension
set pos to the offset of " ." in newText
if pos > 0 then
set newText to ((characters 1 thru (pos - 1) of newText) as text) & (characters (pos + 1) thru -1 of newText) as text
end if
--remove leading spaces
if character 1 of newText = " " then
set newText to characters 2 thru -1 of newText as text
end if
---BROKEN SECTION
--remove trailing spaces
if (last character of newText) = " " then
set newText to (characters 1 thru -2 of newText) as text
end if
end repeat
return newText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
但是,如果您的目标只是去掉空格,则可以使用文本项分隔符更有效地做到这一点:
on stripSpaces(thisText)
set tid to my text item delimiters
set my text item delimiters to " " -- break text at spaces
set textParts to text items of thisText
set my text item delimiters to "" -- recombine text without spaces
set strippedText to textParts as text
set my text item delimiters to tid
return strippedText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
我来晚了一点。 Ted Wrigley 紧盯着球,非常正确地注意到,最简洁、最有效的解决方案是 text item delimiters
。在我看来,我认为他提供了迄今为止最合适的答案,这归功于他,这基本上只是一个 follow-up 来说明可以用更紧凑的 two-line 处理程序:
to removeAllWhitespace from input as text
set text item delimiters to {pi, space, tab, linefeed, return}
return the input's text items as text
end removeAllWhitespace
我还冒昧地清除了除 space
之外的所有(传统)空白字符,即 tab
字符和 new-line 字符。如果您愿意,您可能可以推断出如何删除这些选项。
调用处理程序:
removeAllWhitespace from " spa . nish . txt "
输出:"spa.nish.txt"
嗯?皮...?
简而言之:随机选择任何不是文本并且不太可能出现在文件名中的内容。如果有疑问:使用 pi ^ pi
.
详细说明: 不要太纠结于pi
:[=17的使用=] 在上面的分隔符列表中作为一个数量本身没有任何意义,它的唯一功能是作为 non-string 允许从文件名中删除列表中所有分隔符的实体,它将包括在 string-form 中出现的任何自身,即 "3.14159265359"
。如果这个字符序列没有出现在文件名中,pi
可能是一个很好的选择来充当这个 "dummy delimiter"。否则,关键是将 pi
换成任何其他 non-string 值。说... pi + 1
?我经常使用 null
、missing value
或 randomly-generated 数字。但是,如果您发现自己懒得生成数字或自己想一个数字,只需使用 pi ^ pi
.
从字符串中删除最后一个字符应该是一段简单的代码,但似乎无缘无故地中断了(无论如何对我来说)。
我正在尝试创建一个简单的脚本来解决同事在文件名和扩展名周围有多余空格时出现的 OneDrive 文件同步问题。
离开很长时间后回到 AppleScript,似乎忘记了一切,只需要了解为什么应该简单的东西似乎让我感到困惑...对我温柔点。
on stripSpaces(thisText)
local newText
local pos
local tempText
set newText to thisText
set tempText to ""
repeat while tempText ≠ newText
set tempText to newText
--remove spaces before extension name
set pos to the offset of ". " in newText
if pos > 0 then
set newText to ((characters 1 thru pos of newText) as text) & (characters (pos + 2) thru end of newText) as text
end if
--remove spaces before extension
set pos to the offset of " ." in newText
if pos > 0 then
set newText to ((characters 1 thru (pos - 1) of newText) as text) & (characters (pos + 1) thru end of newText) as text
end if
--remove leading spaces
if character 1 of newText = " " then
set newText to characters 2 thru end of newText as text
end if
---BROKEN SECTION
--remove trailing spaces
if (last character of newText) = " " then
set newText to (characters 1 thru (end of newText) - 1) as text
end if
end repeat
return newText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
错误 "Can’t get end of \" 水疗中心。完成。文本文件 \”。”从“spa.nish.txt”的最后一个插入点开始的数字 -1728
使用 text 1 thru -1 of newText
获取文本范围要容易得多,其中 -1 是最后一个字符。这也避免了所有 as text
强制转换。
on stripSpaces(thisText)
local newText
local pos
local tempText
set newText to thisText
set tempText to ""
repeat while tempText ≠ newText
set tempText to newText
--remove spaces before extension name
set pos to the offset of ". " in newText
if pos > 0 then
set newText to text 1 thru pos of newText & text (pos + 2) thru -1 of newText
end if
--remove spaces before extension
set pos to the offset of " ." in newText
if pos > 0 then
set newText to text 1 thru (pos - 1) of newText & text (pos + 1) thru -1 of newText
end if
--remove leading spaces
if first character of newText = space then
set newText to text 2 thru -1 of newText
end if
--remove trailing spaces
if last character of newText = space then
set newText to text 1 thru -2 of newText
end if
end repeat
return newText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
借助 AppleScriptObjC 的一点帮助,整个处理程序可以减少到两行
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
on stripSpaces(thisText)
set nsText to current application's NSString's stringWithString:thisText
return (nsText's stringByReplacingOccurrencesOfString:" " withString:"") as text
end stripSpaces
log stripSpaces(" spa . nish . txt ")
您问题的直接答案是您不应在此上下文中使用 'end',而应使用“-1”表示最后一个字符,“-2”表示倒数第二个字符等等。结果最终会是这样的:
on stripSpaces(thisText)
local newText
local pos
local tempText
set newText to thisText
set tempText to ""
repeat while tempText ≠ newText
set tempText to newText
--remove spaces before extension name
set pos to the offset of ". " in newText
if pos > 0 then
set newText to ((characters 1 thru pos of newText) as text) & (characters (pos + 2) thru -1 of newText) as text
end if
--remove spaces before extension
set pos to the offset of " ." in newText
if pos > 0 then
set newText to ((characters 1 thru (pos - 1) of newText) as text) & (characters (pos + 1) thru -1 of newText) as text
end if
--remove leading spaces
if character 1 of newText = " " then
set newText to characters 2 thru -1 of newText as text
end if
---BROKEN SECTION
--remove trailing spaces
if (last character of newText) = " " then
set newText to (characters 1 thru -2 of newText) as text
end if
end repeat
return newText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
但是,如果您的目标只是去掉空格,则可以使用文本项分隔符更有效地做到这一点:
on stripSpaces(thisText)
set tid to my text item delimiters
set my text item delimiters to " " -- break text at spaces
set textParts to text items of thisText
set my text item delimiters to "" -- recombine text without spaces
set strippedText to textParts as text
set my text item delimiters to tid
return strippedText
end stripSpaces
log stripSpaces(" spa . nish . txt ")
我来晚了一点。 Ted Wrigley 紧盯着球,非常正确地注意到,最简洁、最有效的解决方案是 text item delimiters
。在我看来,我认为他提供了迄今为止最合适的答案,这归功于他,这基本上只是一个 follow-up 来说明可以用更紧凑的 two-line 处理程序:
to removeAllWhitespace from input as text
set text item delimiters to {pi, space, tab, linefeed, return}
return the input's text items as text
end removeAllWhitespace
我还冒昧地清除了除 space
之外的所有(传统)空白字符,即 tab
字符和 new-line 字符。如果您愿意,您可能可以推断出如何删除这些选项。
调用处理程序:
removeAllWhitespace from " spa . nish . txt "
输出:"spa.nish.txt"
嗯?皮...?
简而言之:随机选择任何不是文本并且不太可能出现在文件名中的内容。如果有疑问:使用 pi ^ pi
.
详细说明: 不要太纠结于pi
:[=17的使用=] 在上面的分隔符列表中作为一个数量本身没有任何意义,它的唯一功能是作为 non-string 允许从文件名中删除列表中所有分隔符的实体,它将包括在 string-form 中出现的任何自身,即 "3.14159265359"
。如果这个字符序列没有出现在文件名中,pi
可能是一个很好的选择来充当这个 "dummy delimiter"。否则,关键是将 pi
换成任何其他 non-string 值。说... pi + 1
?我经常使用 null
、missing value
或 randomly-generated 数字。但是,如果您发现自己懒得生成数字或自己想一个数字,只需使用 pi ^ pi
.