OSX Services - character substitution + for _ - macos

I've created a service to use primarily in a browser for searching IMDB, so instead of copying and pasting the film's name I just select the text and run the service I created which will automatically search IMDB for the selected text. This works perfect.
I was hoping to do the same for Wikipedia and so i've been trying to modify the same service but have come across a problem. The search query places a "+" between each word.
This doesn't work for Wikipedia. They place underscores between their words.
I wondered how I can substitute the + for _?
This is what I currently have
open "https://en.wikipedia.org/wiki/$(ruby -rcgi -e 'print CGI.escape $<.read.chomp')"
Kinds regards and Merry Christmas :)

You can substitute every space for underscore with the gsub() command before the escape command.
open "https://en.wikipedia.org/wiki/$(ruby -rcgi -e 'print CGI.escape $<.read.chomp.gsub(" ", "_")')"

Related

Ruby Group regular expression to match only first occurence [duplicate]

This question already has answers here:
Regular expression to stop at first match
(9 answers)
Closed 2 years ago.
I have this gigantic ugly string:
J0000000: Transaction A0001401 started on 8/22/2008 9:49:29 AM
J0000010: Project name: E:\foo.pf
J0000011: Job name: MBiek Direct Mail Test
J0000020: Document 1 - Completed successfully
I'm trying to extract pieces from it using regex. In this case, I want to grab everything after Project Name up to the part where it says J0000011: (the 11 is going to be a different number every time).
Here's the regex I've been playing with:
Project name:\s+(.*)\s+J[0-9]{7}:
The problem is that it doesn't stop until it hits the J0000020: at the end.
How do I make the regex stop at the first occurrence of J[0-9]{7}?
Make .* non-greedy by adding '?' after it:
Project name:\s+(.*?)\s+J[0-9]{7}:
Using non-greedy quantifiers here is probably the best solution, also because it is more efficient than the greedy alternative: Greedy matches generally go as far as they can (here, until the end of the text!) and then trace back character after character to try and match the part coming afterwards.
However, consider using a negative character class instead:
Project name:\s+(\S*)\s+J[0-9]{7}:
\S means “everything except a whitespace and this is exactly what you want.
Well, ".*" is a greedy selector. You make it non-greedy by using ".*?" When using the latter construct, the regex engine will, at every step it matches text into the "." attempt to match whatever make come after the ".*?". This means that if for instance nothing comes after the ".*?", then it matches nothing.
Here's what I used. s contains your original string. This code is .NET specific, but most flavors of regex will have something similar.
string m = Regex.Match(s, #"Project name: (?<name>.*?) J\d+").Groups["name"].Value;
I would also recommend you experiment with regular expressions using "Expresso" - it's a utility a great (and free) utility for regex editing and testing.
One of its upsides is that its UI exposes a lot of regex functionality that people unexprienced with regex might not be familiar with, in a way that it would be easy for them to learn these new concepts.
For example, when building your regex using the UI, and choosing "*", you have the ability to check the checkbox "As few as possible" and see the resulting regex, as well as test its behavior, even if you were unfamiliar with non-greedy expressions before.
Available for download at their site:
http://www.ultrapico.com/Expresso.htm
Express download:
http://www.ultrapico.com/ExpressoDownload.htm
(Project name:\s+[A-Z]:(?:\\w+)+.[a-zA-Z]+\s+J[0-9]{7})(?=:)
This will work for you.
Adding (?:\\w+)+.[a-zA-Z]+ will be more restrictive instead of .*

Select multiple words and characters using GREP

I need some GREP help. I'm trying to search for text in an InDesign file that has lesser-than "<" and greater-than ">" characters on either end. The text could be one word or more and could include spaces and even numbers. But, here's here's the catch, there may be multiple words on a line, such as , , <12 peaches> and <3 plums>.
I tried using <(.+)> but this picks up the whole paragraph and removes the beginning and ending brackets < > but leaves the ones in the middle.
Anyone know the proper wildcard structure that would find any text or number between these brackets and even if more than one set of "<>" appear in a single paragraph?
FYI, GREP in InDesign is not exactly the same as it's used on the web.
The + metacharacter is greedy meaning it tends to catch more than needed. You can restrain it with a question mark like this :
<.+?>
or change your pattern with
<[^>]+>

Regex string for Sublime Text to find email address between two commas

I'm new to regex's and Sublime's and am having issues trying to do a find/replace on all email addresses in a csv file.
I thought it would be reasonably straightforward but seem to be heading down the rabbit hole at a great rate of knots.
Data looks like;
data,data,email#address.com,data,data etc NB: there are about 100 fields per record and about 300 records
My thought was to look for the # symbol, then go left and right until I get to the comma and then replace with my new email address but I just can't get a win.
Any thoughts or am I using the wrong tool for the job?
(Also tagging with Ruby as if I need to do some scripting then I'll try to get figure it out in Ruby)
Thanks,
Liam
user2141046's expression won't find an email address like- "a.b#c.com"
I would suggest using:
[a-zA-Z0-9.!#$%&'+-/=?\^_`{|}~-]+#[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)
Source
I'm not familiar with the ruby language, but a regex that finds what you want is:
\w+\#\w+\.\w+
with the \. maybe unneeded (depending on language).
a perl one-liner that does the exact thing:
perl -pi -e 's/\w+\#\w+\.\w+/<your new email here>/g' <csv file here>
note
make sure you use \# in the enw email in the one liner i wrote, meaning new_email\#server.com
Try this:
[a-zA-Z0-9.!#$%&'*+-/=?\^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*
It worked perfectly on a very long csv file filled with emails and all other kinds of stuff.
[a-zA-Z0-9.!#$%&'+-/=?\^_`{|}~-]+#[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)
will not work fine, because some domains have 2 or more levels (like com.br)
Use:
[a-zA-Z0-9.!#$%&'+-/=?\^_`{|}~-]+#[a-zA-Z0-9-]+(?:.[\.a-zA-Z0-9-]+)

Windows SED command - simple search and replace without regex

How should I use 'sed' command to find and replace the given word/words/sentence without considering any of them as the special character?
In other words hot to treat find and replace parameters as the plain text.
In following example I want to replace 'sagar' with '+sagar' then I have to give following command
sed "s/sagar/\\+sagar#g"
I know that \ should be escaped with another \ ,but I can't do this manipulation.
As there are so many special characters and theie combinations.
I am going to take find and replace parameters as input from user screen.
I want to execute the sed from c# code.
Simply, I do not want regular expression of sed to use. I want my command text to be treated as plain text?
Is this possible?
If so how can I do it?
While there may be sed versions that have an option like --noregex_matching, most of them don't have that option. Because you're getting the search and replace input by prompting a user, you're best bet is to scan the user input strings for reg-exp special characters and escape them as appropriate.
Also, will your users expect for example, their all caps search input to correctly match and replace a lower or mixed case string? In that case, recall that you could rewrite their target string as [Ss][Aa][Gg][Aa][Rr], and replace with +Sagar.
Note that there are far fewer regex characters used on the replacement side, with '&' meaning "complete string that was matched", and then the numbered replacment groups, like \1,\2,.... Given users that have no knowledge or expectation that they can use such characters, the likelyhood of them using is \1 in their required substitution is pretty low. More likely they may have a valid use for &, so you'll have to scan (at least) for that and replace with \&. In a basic sed, that's about it. (There may be others in the latest gnu seds, or some of the seds that have the genesis as PC tools).
For a replacement string, you shouldn't have to escape the + char at all. Probably yes for \. Again, you can scan your user's "naive" input, and add escape chars as need.
Finally if you're doing this for a "package" that will be distributed, and you'll be relying on the users' version of sed, beware that there are many versions of sed floating around, some that have their roots in Unix/Linux, and others, particularly of super-sed, that (I'm pretty sure) got started as PC-standalones and has a very different feature set.
IHTH.

How to enumerate unique characters in a UTF-8 document? With sed?

I'm converting some Polish<->English dictionaries from RTF to HTML. The Polish special characters are coming out fine. But IPA (International Phonetic Alphabet) glyphs get changed to funny things, depending on what program I use for conversion. For example, /ˈbiːrɪ/ comes out as /ÈbiùrI/ or /∪βιρΙ/.
I'd like to correct these documents with a search & replace, but I want to make sure I don't miss any characters and don't want to manually pore over dictionary entries. I'd like to output a list of all unique, NON-ascii characters in a document.
I found this thread:
Find Unique Characters in a File
... and I tried the following two proposals:
sed -e "s/./\0\n/g" inputfile | sort -u
sed -e "s/(.)/\1\n/g" inputfile | sort -u
They both work nicely, and seem to both generate the same output. My problem is that they only output standard ASCII characters, and what I'm looking for is exactly the opposite.
The sed tool looks awesome, but I don't have time to learn it right now (though I intend to later). I'm hoping the solution will be clear to someone who's already mastered this tool, and they can save me a lot of time. [-:
Thanks in advance!
This is not a sed solution but a Python solution. It reads the contents of a file, takes it as UTF-8 and then turns it into a set (thus throwing away duplicates), throws away ASCII characters (0-127), sorts it and then joins it back together again with a blank line between each character:
'\n'.join(sorted(set(unicode(open(inputfile).read(), 'utf-8')) - set(chr(i) for i in xrange(128))))
As something you'd run from the command line if you felt so inclined,
python -c "print '\n'.join(sorted(set(unicode(open('inputfile').read(), 'utf-8')) - set(chr(i) for i in xrange(128))))"
(You could also use ''.join instead of '\n'.join which would list the characters without a newline in between.)

Resources