【问题标题】:If string does NOT contain and REGEX如果字符串不包含和 REGEX
【发布时间】:2019-04-11 21:40:56
【问题描述】:

我正在寻找一种在applescript中编写以下javascript代码的方法:如果条件为假,那么我想做点什么。

var regEx = /\d{5}/g;
var str = 'This string contains 12345';

if (!regEx.test(str)){
    do something
}

下面是我启动的applescript,但它不起作用。

set str to 'This string contains 12345'
set regEx to <NOT SURE HOW APPLESCRIPT HANDLES THIS>

if string does contains "12345" then
 do something
end if 

在 Javascript 中! = 没有。 applescript中的等价物是什么?以及如何处理正则表达式?

我的总体目标是找出所选的查找器窗口是否在文件夹名称中不包含任何 5 位数字组合。

【问题讨论】:

  • 原版 AppleScript 无法处理正则表达式。您可以使用 Foundation 框架中的 SatImage OSAX 或 NSRegularExpression
  • 感谢@vadian,但这对我来说有点多。忘记正则表达式,你将如何搜索包含 5 位数字的字符串?
  • 你也可以选择确实知道正则表达式的东西,例如set bool to (do shell script "/usr/bin/ruby -e 'puts !(\"" &amp; str &amp; "\" =~ /\\d{5}/).nil?'") = "true"
  • 谢谢@red_menace。在测试和摆弄你的建议之后,就像正则表达式一样。

标签: applescript


【解决方案1】:

tl;dr 对于&gt;= OSX 10.8 的任何macOS 版本,您需要替换grep-P 选项(如 中所示)解决方案” 部分)与-E 选项 - 如本文底部的“不同的grep 实用程序”部分所述。


正如 cmets 中正确指出的那样...

Vanilla AppleScript 无法处理正则表达式。 - vadian

所以你需要

掏出一些知道正则表达式的东西 - red_menace


解决方案:

要以类似于 JavaScript 的 test() 方法的方式满足您对普通 AppleScript 的要求,请考虑使用自定义 AppleScript 子例程,如下所示:

子程序:

on regExpTest(str, re)      
  set statusCode to do shell script "grep -q -P " & quoted form of re & ¬
    " <<<" & quoted form of str & " 2>/dev/null; echo $?"

  if statusCode is equal to "0" then
    return true
  else
    return false
  end if
end regExpTest

用法:

set regExp to "\\d{5}"
set str to "This string contains 12345"

if regExpTest(str, regExp) then
  display dialog "It DOES match so let's do something"
end if

运行上述脚本将显示一个带有给定消息的对话框,因为正则表达式和指定字符串之间存在匹配项。

注意: AppleScript 字符串使用反斜杠作为转义字符,因此您会注意到\d 元字符已通过额外的反斜杠进一步转义,即\\d

不等式运算符:

在 Javascript 中 != 没有。 applescript中的等价物是什么?以及如何处理正则表达式?

AppleScript 的 inequality operators 类似于 JavaScripts inequality operator (!=) 是:

≠
is not
isn't
isn't equal [to]
is not equal [to]
doesn't equal
does not equal

因此,鉴于您的 JavaScript if 声明:

if (!regEx.test(str)){
  // do something
}

我们可以实现相同的逻辑,(再次使用前面提到的自定义regExpTest 子程序),使用以下代码:

set regExp to "\\d{5}"
set str to "This string contains 1234"

if regExpTest(str, regExp) ≠ true then
  display dialog "It DOES NOT match so let's do something"
end if

注意str值只包含四个连续的数字,即1234

这次运行上述脚本将显示一个对话框,其中包含给定消息,因为正则表达式和指定字符串之间存在 NOT 匹配项。

可以对上述 AppleScript if 语句进行许多变体,以实现相同的所需逻辑。例如;

if regExpTest(str, regExp) is not equal to true then
  ...
end if
if regExpTest(str, regExp) = false then
  ...
end if

等等……


regExpTest子程序解释:

前面提到的regExpTest AppleScript 子例程本质上是利用do shell script 命令来运行以下代码,您可以通过 macOS Terminal 应用程序直接运行这些代码。例如,在您的 Terminal 应用程序中运行以下两个命令:

grep -q -P "\d{5}" <<<"This string contains 12345" 2>/dev/null; echo $?

打印:

0

grep -q -P "\d{5}" <<<"This string contains 1234" 2>/dev/null; echo $?

打印:

1


编辑:不同的grep 实用程序:

正如user3439894 的评论中所指出的,Mac 上安装的grep 实用程序的某些版本似乎不支持-P 选项,该选项确保RegExp 模式被解释为Perl 正则表达式。我选择使用 Perl 正则表达式的原因是因为它们更接近于 JavaScript 中使用的正则表达式。

但是,如果您通过命令行运行 man grep 并发现您的 greputility 不提供 -P 选项,则在 regExpTest 子例程中更改以下代码行:

set statusCode to do shell script "grep -q -P " & quoted form of re & ¬
  " <<<" & quoted form of str & " 2>/dev/null; echo $?"

改为:

set statusCode to do shell script "grep -q -E " & quoted form of re & ¬
  " <<<" & quoted form of str & " 2>/dev/null; echo $?"

注意:-P 选项已更改为 -E,因此该模式现在被解释为扩展正则表达式 (ERE)。

速记元字符\d

您可能还发现需要将正则表达式模式的赋值从:

set regExp to "\\d{5}"

set regExp to "[0-9]{5}"

这次,速记元字符\d(用于匹配数字)已被替换为等效的字符类[0-9]

【讨论】:

  • 在股票 macOS 中,您的 grep command 使用 -P option 失败,因为 选项。使用 -E option 和 stock macOS grep command。在例如macOS High Sierra grep --version command 返回 grep (BSD grep) 2.5.1-FreeBSD。要使用-P 选项,需要GNU grep
  • 感谢@RobC 的解释,因为它非常彻底:-)。即使我得到了 red_menace 建议的 do shell 脚本,我也会测试/研究你分享的内容。致 user3439894,感谢您添加的评论。
  • @user3439894 - 感谢有关兼容性的反馈 - 添加注释以回答。出于兴趣,您的 grep (BSD grep) 2.5.1-FreeBSD 实用程序是否成功处理 ERE 中的速记元字符 \d(即使用 -E 选项) - 或者您是否必须将其作为字符类提供,即 [0-9] ?跨度>
  • @RobC,使用您提供的 command 示例,同时使用 -E option 而不是 -P 确实可以正常工作,以及为什么我建议使用它。 BSD grepmacOS 的默认 grep,而必须手动安装 GNU grep 才能使用 -P 选项。顺便说一句,很好的答案! +1
  • @RobC,好的,Mac OS X 10.7 Lion 是最后一个默认附带 GNU grep 的版本,它已经BSD grepOS X 10.8 Mountain Lion.
【解决方案2】:

正如其他人所说,您可以通过 AppleScript-ObjC 桥使用 Foundation 框架的 NSRegularExpression

也就是说,Objective-C API 虽然功能强大,但并不完全对 AppleScripter 友好,所以几年前我拼凑了一些 “standard libraries”,它们将许多通用功能封装为很好的原生 AppleScript 命令。

例如这是使用 Text 库的 search text 命令最接近您的 JavaScript 的等效项:

use script "Text"

set str to "This string contains 12345"

set foundMatches to search text str for "\\d{5}" using pattern matching

if foundMatches is not {} then
    -- do something
end if

无法引起太多兴趣,因此我不再进行开发或支持。但是它们是免费和开放的(就我而言是公共领域)并且在当前版本的 macOS AFAIK 中仍然可以正常工作,所以请自助。

【讨论】:

    猜你喜欢
    • 2012-06-13
    • 1970-01-01
    • 2021-06-02
    • 2010-11-22
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    相关资源
    最近更新 更多