最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Google Forms set regular expression in Apps Script - Stack Overflow

programmeradmin0浏览0评论

I'm making a Google Form via Apps Script and need to set a field to only accept US 10-digit phone numbers. I found this regular expression which works if I set it via the Form Editor: ^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$.

But again, I need this to work from Apps Script. My code snippet is as follows:

let form = FormApp.create("new Order");
let phoneNumber = form.addTextItem().setTitle("Textable phone number").setRequired(true);
  phoneNumber.setValidation(FormApp.createTextValidation()
      .requireTextMatchesPattern("^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$")
      .build());

This throws Exception: Invalid data updating form. When I change it to .requireTextMatchesPattern(/^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/) the script runs and completes, but then it's impossible to fill out the form because a standard phone number throws an error saying must match pattern.

So, how do I set a regular expression pattern in Apps Script that will properly allow input?

I'm making a Google Form via Apps Script and need to set a field to only accept US 10-digit phone numbers. I found this regular expression which works if I set it via the Form Editor: ^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$.

But again, I need this to work from Apps Script. My code snippet is as follows:

let form = FormApp.create("new Order");
let phoneNumber = form.addTextItem().setTitle("Textable phone number").setRequired(true);
  phoneNumber.setValidation(FormApp.createTextValidation()
      .requireTextMatchesPattern("^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$")
      .build());

This throws Exception: Invalid data updating form. When I change it to .requireTextMatchesPattern(/^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/) the script runs and completes, but then it's impossible to fill out the form because a standard phone number throws an error saying must match pattern.

So, how do I set a regular expression pattern in Apps Script that will properly allow input?

Share Improve this question edited Feb 4 at 20:10 leylou 5791 silver badge10 bronze badges asked Feb 3 at 21:43 SpencerSpencer 4577 silver badges24 bronze badges 9
  • Can you try ^(\\+0?1\\s)?\\(?\\d{3}\\)?[\\s.-]\\d{3}[\\s.-]\\d{4}$ to see if that works? When completed, it should output the Regular Expression that Matches the pattern ^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$ in the Google Form. – Saddles Commented Feb 3 at 22:35
  • When ^(+0?1\\s)?(?\\d{3})?[\\s.-]\\d{3}[\\s.-]\\d{4}$ is manually added; the form simply states, Please enter a valid regular expression. Kindly Edit the question and confirm if that regular expression is what worked for you in the Google Form. – Saddles Commented Feb 3 at 22:48
  • "^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$" is the match pattern on the test form that I manually used. That is what I put in the question. SO seems to be eating the first \ – Spencer Commented Feb 3 at 23:40
  • 1 Yes, I know. And that pattern works when I manually apply it. But I cannot get it to apply via GAS – Spencer Commented Feb 3 at 23:54
  • 1 That works! I need to adjust the regex so that it can accept either ########## or ###-###-####, but at least it works to set it from the script. Thanks! – Spencer Commented Feb 4 at 4:42
 |  Show 4 more comments

2 Answers 2

Reset to default 1

Escaping special characters in regexes

That question refers to the requireTextMatchesPattern() method that expects a regex string rather than a RegExp object. The problem is that Javascript strings and regexes both use the backslash \ to escape certain special characters, but not all the escapes have the same meaning in the two contexts.

There are many special characters in regular expressions, including:

.*+?^${}()|[]\

The regex in the question uses some of those characters literally, such as searching for an instance of +. To do that, you must escape the special character by adding a backslash \ prefix. That is easy to do when you use a JavaScript regex literal, but more tricky when you need to use a JavaScript string literal. Notably, to get an actual backslash in a JavaScript string literal, you need to escape it as in \\.

Since the string regex requires backslashes, you need to double those backslashes in the JavaScript string in order for them to be interpreted correctly. To get the regex string ^(\+0)$, where + is a literal rather than a special character, you need to use the JavaScript string '^(\\+0)$'.

To make the regex string work, do the same with all special characters you need to escape in the string, like this:

function getFormWithRegexValidation() {
  const phoneNumberPattern = '^(\\+0?1\\s)?\\(?\\d{3}\\)?[-.\\s]\\d{3}[-.\\s]\\d{4}$';
  const phoneNumberValidation = FormApp.createTextValidation()
    .requireTextMatchesPattern(phoneNumberPattern)
    .build();
  const form = FormApp.create('new Order');
  form.addTextItem()
    .setTitle('Textable phone number')
    .setRequired(true)
    .setValidation(phoneNumberValidation);
  return form;
}

In the event you're not working with string literals but need to escape all regex special characters in a string variable, for example in the input received from a user, use this utility function:

/**
* Escapes special characters such as \ ( ) [ ].
*
* @param {String} string The text string to escape.
* @return {String} The escaped text string.
*/
function escapeRegExCharacters_(string) {
  // version 1.1, written by --Hyde, 9 November 2018
  //  - adapted from https://developer.mozilla./en-US/docs/Web/JavaScript/Guide/Regular_Expressions
  return String(string).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

See Using special characters in strings.

Note: @doubleunary's answer is correct. This is to provide additional information about what's going on.

When the script is tested, the error Exception: Invalid data updating form. shows up due to the pattern being invalid.

As per Escaping:

To match a literal backslash, you need to escape the backslash. For instance, to match the string "C:\" where "C" can be any letter, you'd use /[A-Z]:\\/ — the first backslash escapes the one after it, so the expression searches for a single literal backslash.

This is why changing the pattern from "^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$" to "^(\\+0?1\\s)?\\(?\\d{3}\\)?[\\s.-]\\d{3}[\\s.-]\\d{4}$" in requireTextMatchesPattern(pattern) worked.

Here's a modified version of your script that also accepts either ########## or ###-###-####:

function myFunction() {
  let form = FormApp.create("new Order");
  let phoneNumber = form.addTextItem().setTitle("Textable phone number").setRequired(true);
  phoneNumber.setValidation(FormApp.createTextValidation()
    .requireTextMatchesPattern("^(\\+0?1\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$|^\\d{9}$")
    .build());
}
发布评论

评论列表(0)

  1. 暂无评论