Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regex help #158

Closed
scripting opened this issue Mar 24, 2020 · 6 comments
Closed

Regex help #158

scripting opened this issue Mar 24, 2020 · 6 comments

Comments

@scripting
Copy link
Owner

@scripting scripting commented Mar 24, 2020

I grok regex, but I have a mental block against working in it. It's weird because I used it all the time when I was a grad student, but after programming on PCs and Macs, I became regex-phobic.

Now I have a problem that should be easily solved by regex.

Let's say I have a URL like this:

http://my.this.how/davewiner/outlinerHowto.opml

I want to generate a file name, just using regex, like this:

/Miami/littleoutliner/publicFiles/users/davewiner/myOutlines/outlinerHowto.opml

I could easily write JavaScript code to do this, but I don't want to when regex is sufficient.

So your assignment is to give me a regex that turns the URL into the corresponding file path.

Thanks! :-)

@danmactough

This comment has been minimized.

Copy link

@danmactough danmactough commented Mar 24, 2020

@scripting I'm not sure what constraints you're operating with, but here's the regex I would probably use:

/\/([^\/]+)$/

That is: capture the group of 1 or more characters other than / following a / until the end of the string.

https://regex101.com/r/w2vPme/1

@defjaf

This comment has been minimized.

Copy link

@defjaf defjaf commented Mar 25, 2020

Do you just need to capture the final filename (outlinerHowto.opml, here) or also the username davewiner? If the latter, you could use

\/([^\/]+)\/([^\/]+)$

and replace with

/Miami/littleoutliner/publicFiles/users/\1/myOutlines/\2
@scripting

This comment has been minimized.

Copy link
Owner Author

@scripting scripting commented Mar 25, 2020

I can see I wasn't clear enough in my explanation.

The URL has two variables in it.

http://my.this.how/[username]/[filename]

Which would translate to this path:

/Miami/littleoutliner/publicFiles/users/[username]/myOutlines/[filename]

Does that help?

@defjaf

This comment has been minimized.

Copy link

@defjaf defjaf commented Mar 25, 2020

Dave @scripting, I think my version will work. (It would fail with escaped backslashes or pathological multiline filenames but these would probably be html-%escaped anyway, although of course this wouldn't unescape them for the filename) They also assume the URLs are alone on a line; otherwise the end-of-line $ will have to change.

Or, do you need to detect the url among other text which is a bit harder?

@tedchoward

This comment has been minimized.

Copy link

@tedchoward tedchoward commented Mar 25, 2020

I always use a tool like https://regexer.com to help me visualize regular expressions when I need to build them.

I created a sample here: https://regexr.com/513s9

Here's the expression in JS:

let filePath = 'http://my.this.how/davewiner/outlinerHowto.opml'.replace(/http:\/\/[^\/]+\/([^\/]+)\/([^\/]+)$/, '/Miami/littleoutliner/publicFiles/users/$1/myOutlines/$2');
@scripting

This comment has been minimized.

Copy link
Owner Author

@scripting scripting commented Mar 29, 2020

A follow-up -- I needed this functionality because I wanted to serve outlines created in LO2 using PagePark, because among other things it's very good at serving outlines as Howtos. All the pages on http://this.how flow this way.

In the end I decided not to use regex, but add a plug-in capability for PagePark. I've wanted this since the beginning, but I waited until I could figure out how to actually do it. I didn't like the two methods I had surfaced:

  1. Reading the file via fs.readFile and running it through eval.

  2. Using the vm module.

I thought I had discovered a perfect way to do it, and in the end it turned out to work very well. It really is perfect. I thought since this is a technical group I'd write it up here, and then include the text in the PagePark repo.

A plug-in is a module

You put a file named filter.js at the top level of the website's directory. The server looks for it, and if it's present, the request flows through the filter. This is a tried-and-true concept in Frontier's web server. We had three filters, firstFilter, pageFilter and finalFilter. This time around I'm trying it with just one filter.

It's a regular Node module that must have at least one exported name -- filter.

It takes two params: an object with information about the request and functions you can call to connect up with PagePark proper and a callback, which you can call to return the three basic values every HTTP request must return, a code, content-type and value.

All my filter does is a bit of string manipulation and then call options.serveFile to do all the stuff PagePark does with serving files. It's a full-featured web server. I didn't want to have to reinvent all that in each filter.

There was one snag in the implementation, Node caches the modules, so you can't iterate over changes to a plug-in without restarting the server. Not acceptable. Luckily you can manage the cache, and delete the cached version before calling it.

I love it because It's a whole private little space to work in and nothing you do there seems to interfere with what's happening in the rest of the server.

You can see how PagePark does this, I've already merged the new changes.

Example

Here's an example of a simple plug-in, almost Hello World level.

https://gist.github.com/scripting/a676b0da36c13576877a91fc77a34ecb

What I like best about it

You can iterate over changes to your plug-ins just by saving. No need to restart anything, or change some configuration file. I find it's as much fun to work on these plug-ins as it was to work on Frontier websites.

Second runner-up thing to like: You can go into the plug-ins with the debugger! That makes a world of difference. Node has no idea it's a plug-in. ;-)

@scripting scripting closed this Apr 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.