【问题标题】:Regex in Google Apps Script practical issue. Forms doesn't read regex as it shouldGoogle Apps 脚本中的正则表达式实际问题。表单不读取正则表达式,因为它应该
【发布时间】:2020-06-06 16:30:02
【问题描述】:

我希望这只是我做的不对。

我一直在使用一个简单的脚本从电子表格中创建一个表单。该脚本似乎工作正常。输出表单将从第三方获得一些输入,以便我可以在我的咨询活动中对其进行分析。

创建表单没什么大不了的,结构很好。但是,在表单创建器脚本正常工作后,我已经开始对其进行验证,这就是我所困的地方。

对于文本验证,我需要使用特定的正则表达式。我的客户需要给我的许多输入将是地点和/或人名,因此,我应该只允许他们使用 A-Z、单个空格、撇号和破折号。

我得到的正则表达式是:

//Regex allowing a **single name** with the first letter capitalized and the occasional use of "apostrophes" or "dashes". 
const reg1stName = /^[A-Z]([a-z\'\-])+/
//Should allow (a single name/surname) like Paul, D'urso, Mac'arthur, Saint-Germaine ecc.
//Regex allowing **composite names and places names** with the first letter capitalized and the occasional use of "apostrophes" or "dashes". It must avoid double spaces, however.
const regNamesPlaces = /^[^\s]([A-Z]|[a-z]|\b[\'\- ])+[^\s]$/  
//This should allow (names/surnames/places' names) like Giulius Ceasar, Joanne D'arc, Cosimo de'Medici, Cosimo de Medici,  Jean-jacques Rousseau, Firenze, Friuli Venezia-giulia, L'aquila ecc.

在脚本中,根据每种情况,这些正则表达式被称为表单文本项的验证模式。

//Validation for single names
 var val1stName = FormApp.createTextValidation()
  .setHelpText("Only the person First Name Here! Use only (A-Z), a single apostrophe (') or a single dash (-).")
  .requireTextMatchesPattern(reg1stName)
  .build();
//Validation for composite names and places names   
 var valNamesPlaces = FormApp.createTextValidation()
  .setHelpText(("Careful with double spaces, ok? Use only (A-Z), a single apostrophe (') or a single dash (-)."))
  .requireTextMatchesPattern(regNamesPlaces)
  .build();

此外,我还有一个“for”循环,可以根据电子表格字段创建表单。到目前为止,一切正常。

 for(var i=0;i<numberRows;i++){
  var questionType = data[i][0]; 
  if (questionType==''){
     continue;
  }
  else if(questionType=='TEXTNamesPlaces'){
   form.addTextItem()
     .setTitle(data[i][1]) 
     .setHelpText(data[i][2])
     .setValidation(valNamesPlaces)
     .setRequired(false);   
  }
  else if(questionType=='TEXT1stName'){
   form.addTextItem()
     .setTitle(data[i][1]) 
     .setHelpText(data[i][2])
     .setValidation(val1stName)
     .setRequired(false);
  }

问题是当我运行脚本并测试生成的表单时。 两种验证类型都可以很好地导入(可以在表单的编辑模式中看到),但是在预览模式下测试时出现错误,好像正则表达式不匹配(抱歉,错误消息是葡萄牙语,我忘了像我对上面的代码所做的那样翻译它们):

A screenshot of the form in edit mode

A screeshot of the form in preview mode

但是,如果我手动从这个正则表达式中删除条“//”它开始工作!

A screenshot of the form in edit mode, Regex without bars

A screenshot of the form in preview mode, Regex without bars

我做错了什么?我不是专业的开发人员,但据我了解,编写没有条形的正则表达式是没有意义的。

如果这是一些阅读正则表达式的 Gforms 模式,我仍然需要所有这些都由创建此表单的 Apps 脚本读取。如果我什至尝试通过没有条形的正则表达式,脚本将无法读取它。

const reg1stName = ^[A-Z]([a-z\'])+
const regNamesPlaces = ^[^\s]([A-Z]|[a-z]|\b[\'\- ])+[^\s]$
//Can't even be saved. Returns: SyntaxError: Unexpected token '^' (line 29, file "Code.gs")

手动传递所有验证不是一种选择。有人可以帮帮我吗?

非常感谢

【问题讨论】:

  • Glenio,如果我不得不猜测的话,我会说解析器正在寻找字符串开头的文字字符 /,然后,当你在 / 之后放置 ^ 时,解析器就会感到困惑因为 ^ 应该表示字符串的开头?另外,在验证姓名时请记住,有些人的名字(例如“St John”)有空格,因此您可能希望在姓名验证中留有空格。干杯!
  • 您的评论让我想起了某些名称甚至可能会缩略并后跟一个点的可能性。谢谢,刚刚补充。我再次运行脚本,使用以下正则表达式 "const reg1stName = /([A-Z][a-z.\'\-])+/ 和 const regNamesPlaces = /([A-Z]|[a-z]|\b[. \'\- ])+[^\s]$/" 没有成功。甚至试图将其简化为:“[A-Za-z]+ 和 /[A-Za-z]+/”,只有没有“条”的那个才有效。

标签: javascript regex google-apps-script google-sheets google-forms


【解决方案1】:

这个

/^[A-Z]([a-z\'\-])+/

将无法工作,因为解析器正在尝试将您的 / 匹配为字符串文字。

这个

^[A-Z]([a-z\'\-])+

也不起作用,因为如果名称带有连字符,您只会匹配连字符。例如,这将匹配“Some-Name”中的“Some-”。另外,也许您也希望像“圣约翰”这样的名字也通过?

我推荐以下:)

^[A-Z][a-z]*[-\.' ]?[A-Z]?[a-z]*

^ 锚定到字符串的开头

[A-Z] 正好匹配 1 个大写字母

[a-z]* 匹配零个或多个小写字母(这使您可以匹配像 D'Urso 这样的名称)

[-\.' ]? 匹配零个或 1 个 -(连字符),. (句点)、'(撇号)或单个空格(.(句点)需要用反斜杠转义,因为 . 对正则表达式来说是特殊的)

[A-Z]? 匹配零个或 1 个大写字母(以防名称中有第二个大写字母,例如 D'Urso、St John、Saint-Germaine)

【讨论】:

  • 好的,谢谢凯莉,但问题是我如何在 Google Script 上完成这项工作。请注意,就像 Stackoverflow 的代码嵌入器所做的那样,Google Script 会将您刚刚编写的正则表达式读取为一半字符串,一半是其他内容。无论如何,它只是一个正则表达式。此外,我预见的另一个障碍是 .requireTextMatchesPattern() 函数需要一个模式,而不是字符串或其他任何东西。如果我写的没有条,我什至无法保存/运行脚本。 Google Apps 脚本立即返回错误“SyntaxError: Unexpected token '^' (line 30, file "Code.gs")”。
  • 您是使用构造函数来创建正则表达式,还是只是试图将其作为字符串分配给验证函数? Google 脚本有一个正则表达式构造函数,您可以创建一个包含这样代码的验证函数,然后将该函数调用为您的验证函数。函数 validateLast(ln) { var regExp = new RegExp("^[A-Z][a-z]*[-\.' ]?[A-Z]?[a-z]*"); var lastName = regExp.exec(ln);记录器.log(lastName); }
  • 我已经尝试过构造函数 ' const reg1Nome = new RegExp("(^[A-Z][a-z]*[-\.' ]?[A-Z]?[a-z]*)") '谷歌表单再次将正则表达式作为条形之间导入,它再次按字面意思解析这些条形。手动删除它们的唯一解决方案。
  • 现在我已经将正则表达式声明为字符串,它起作用了! const reg1Nome = "(^[A-Z][a-z]*[-\.' ]?[A-Z]?[a-z]*)" Google 表单导入了没有条形的正则表达式,并且能够将其用作适当的验证器。泰凯莉!
猜你喜欢
  • 2015-04-11
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多