我正在创建一个Gmail附件,该附件将电子邮件的某些信息发送到后端终结点,并且为此,它必须以以下方式选择和格式化电子邮件的电子邮件地址:
GmailMessage.getFrom()
或GmailMessage.getTo()
的结果是带有电子邮件格式的字符串,则该地址是地址,不应执行任何格式。GmailMessage.getFrom()
或GmailMessage.getTo()
的结果是格式为John Doe <john@doe.com>
的字符串,则地址应为尖括号之间的子字符串。所以我为此编写了以下代码
for (var i = 0; i < messages.length; i++) {
var address = '';
var name = '';
var from = messages[i].getFrom()
var to = messages[i].getTo();
Logger.log(from);
Logger.log(to);
if (messages[i].isInInbox()) {
Logger.log('inbox'); // (*)
if (/<(.*?)>/g.test(from)) {
Logger.log(/<(.*?)>/g.test(from));
Logger.log('true');
address = /<(.*?)>/.exec(from)[1];
} else {
Logger.log(/<(.*?)>/g.test(from)); // (**)
Logger.log('false');
address = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/g.exec(from)[0];
}
name = /^(.*?)@/.exec(address);
} else {
Logger.log('sent');
if (/<(.*?)>/g.test(to)) {
Logger.log(/<(.*?)>/g.test(to));
Logger.log('true');
address = /<(.*?)>/.exec(to)[1];
} else {
Logger.log(/<(.*?)>/g.test(to));
Logger.log('false');
address = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/g.exec(to)[0];
}
name = /^(.*?)@/.exec(address);
}
}
邮件是GmailMessage对象的数组。
问题是,在其中一个收件箱消息中,“ {from}”地址对于正则表达式/<(.*?)>/g
评估为true,但仍输入else语句。
为了更清楚地说明它,记录器的输出如下:
[19-10-14 13:52:14:750 PDT] "Foo Bar" <foo@bar.com>
[19-10-14 13:52:14:750 PDT] john@doe.com <---- selected address
[19-10-14 13:52:14:751 PDT] sent
[19-10-14 13:52:14:751 PDT] false <---- it's a "simple string", not enclosed by <>
[19-10-14 13:52:14:752 PDT] false
[19-10-14 13:52:14:753 PDT] John Doe <john@doe.com> <---- selected address
[19-10-14 13:52:14:754 PDT] "Foo Bar" <foo@bar.com>
[19-10-14 13:52:14:755 PDT] inbox
[19-10-14 13:52:14:755 PDT] true <---- enclosed by <>
[19-10-14 13:52:14:755 PDT] true
[19-10-14 13:52:14:757 PDT] "Foo Bar" <foo@bar.com>
[19-10-14 13:52:14:757 PDT] John Doe <john@doe.com> <---- selected address
[19-10-14 13:52:14:757 PDT] sent
[19-10-14 13:52:14:758 PDT] true <---- enclosed by <>
[19-10-14 13:52:14:758 PDT] true
[19-10-14 13:52:14:760 PDT] John Doe <john@doe.com> <---- selected address
[19-10-14 13:52:14:760 PDT] "Foo Bar" <foo@bar.com>
[19-10-14 13:52:14:761 PDT] inbox
[19-10-14 13:52:14:761 PDT] true <---- enclosed by <>
[19-10-14 13:52:14:761 PDT] false <---- it's entering to the else statement nonetheless
关于为什么会发生这种奇怪行为的任何线索?我非常努力地弄清楚这段代码有什么问题,但我真的不知道这可能是什么。
编辑:我进行了更多测试,但奇怪的是,如果将表达式/<(.*?)>/g.exec(from)
放在null
(*)下方并等于Logger.log('inbox')
,则表达式[<john@doe.com>, john@doe.com]
等于https://example.com/
https://example.com/path
application://example.com/path
application://example
。 http:\\example.com
在else语句(**)内。谁能解释这个行为?
答案 0 :(得分:1)
是引起问题的全局修饰符。带有全局修饰符的正则表达式在调用之间(包括对test()的调用)是有状态的。保持状态是为了使像exec()这样的事情可以迭代地调用以返回下一个匹配项。由于您在表达式中使用文字,因此解释程序仅将其优化为表达式的一个实例。同一实例+有状态+使用相同的arg ==多次调用test()。
删除这些表达式中的g
标志,就可以了。由于您正在测试任何匹配项,因此甚至不需要它的使用方式。
答案 1 :(得分:-2)
var patt = new RegExp("e");
var res = patt.test(str);
根据您的情况,请按以下步骤修改代码:
var patt = new RegExp("/<(.*?)>/g");
if (messages[i].isInInbox()) {
Logger.log('inbox'); // (*)
if (patt.test(from)) {
Logger.log(patt.test(from));
Logger.log('true');
address = /<(.*?)>/.exec(from)[1];
} else {
Logger.log(patt.test(from)); // (**)
Logger.log('false');
...
注意:exec()还期望正确定义RegExp。