如果字符串不包含和 REGEX

If string does NOT contain and REGEX

我正在寻找一种在 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 中的等价物是什么?以及如何处理 RegEx?

我的总体目标是查明选择的 window 文件夹名称中是否不包含任何 5 位数字组合。

tl;dr 对于 >= OSX 10.8 的任何 macOS 版本,您需要替换 grep-P 选项(如以下 "Solution" 部分所示)与 -E 选项 - 如 "Different grep utilities" 中所述此 post.

底部的 部分

正如评论中正确指出的那样...

Vanilla AppleScript can't handle regex. - vadian

所以你需要

shell out to something that does know regex - red_menace


解决方案:

为了以类似于 JavaScript 的 test() 方法的方式使用 vanilla 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

不等式运算符:

In Javascript != does not. What is the equivalent in applescript? and how do I handle RegEx?

AppleScript 的 inequality operators that are analogous to 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 实用程序:

正如安装在 Mac 上的 user3439894 it seems that some versions of the grep 实用程序的评论中所述,不支持确保 RegExp 模式被解释为 Perl 正则表达式的 -P 选项。我选择使用 Perl 正则表达式的原因是因为它们与 JavaScript.

中使用的正则表达式更加一致

但是,如果您通过命令行 运行 man grep 发现您的 grep 实用程序不提供 -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)。

shorthand元字符\d

您可能还会发现您需要更改正则表达式模式的分配:

set regExp to "\d{5}"

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

这次 shorthand 元字符 \d(用于匹配数字)已被等效字符 class [0-9] 替换。

正如其他人所说,您可以通过 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

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