1

I have a hash of "allowed links" to render on my rails backend, something like this

    ALLOWED_URLS = {
      "vimeo": {
          :regex => "/https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/",
},
      "youtube": {
          :regex => "/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/",
    }

In each of the stored values, I have a regular expression to try if a link is from youtube or Vimeo and the video id I have tried them both and they work perfectly.

But when I pass that variable to my CoffeeScript and convert it to a JSON, the regex does not work because it comes with quotation marks, like this:

"/https?://(?:www.|player.)?vimeo.com/(?:channels/(?:w+/)?|groups/([^/]*)/videos/|album/(d+)/video/|video/|)(d+)(?:$|/|?)/"

and when I try to test it, this error is shown...

Uncaught SyntaxError: Invalid regular expression: //https?://(?:www.|player.)?vimeo.com/(?:channels/(?:w+/)?|groups/([^/]*)/videos/|album/(d+)/video/|video/|)(d+)(?:$|/|?)//: Nothing to repeat at String.matc

I've tried to put the regex without the quotation marks on the backend, but the result is the same

What can I do??

8
  • 1
    Store it as a string literal, with appropriate backslash escaping, then use a regexp constructor when you initialize the regex object. Commented Mar 17, 2020 at 22:53
  • @WiktorStribiżew i don't know how to do that, can you show me an example please? Commented Mar 17, 2020 at 23:56
  • Or better, store them as Regex literals: regex: /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|.../ (i.e. drop the surround quotes). Commented Mar 18, 2020 at 0:07
  • @muistooshort that doesn't work for me, if I try to access that without the .to_json I get a "missing / (unclosed regex)" error, I think the problem is that I'm using .to_json, but i dont know Commented Mar 18, 2020 at 0:19
  • Sorry, missed the CoffeeScript part. Why not just write them in CoffeeScript to begin with? Ruby and JavaScript regexes are different anyway. Commented Mar 18, 2020 at 1:01

1 Answer 1

2

There are two separate problems here:

  1. Escaping is going to be a nightmare because everyone (Ruby, (Java|Coffee)Script, regexes) wants to use \ as an escape character.
  2. Converting a dynamic string into a (Java|Coffee)Script regex.

Part (2) is pretty easy, get the regex into a JavaScript string and then use the RegExp constructor in your JavaScript:

# In your CoffeeScript...
str = '^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*'
re  = new RegExp(str)

So now you need to get this string into your CoffeeScript:

'^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*'

Build the string in Ruby (using single quotes to reduce the escapes and don't include the leading and trailing slashes):

youtube: {
  regex: '^.*(youtu.be/|v/|u/\w/|embed/|watch\?v=|&v=)([^#&?]*).*'
}

and then you can use to_json to get into JavaScript:

<script type="text/javascript">
  let str = <%= ALLOWED_URLS[:youtube][:regex].to_json %>;
  let re  = new RegExp(str);
</script>

That will be equivalent to saying:

let re = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/;

in JavaScript.

Sign up to request clarification or add additional context in comments.

2 Comments

Holy cow, thanks! you're a genius! Thank you so much!
Again, thank you, I just finished my task, you're my hero!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.