Sublime Forum

Regex snippet question

#1

I am trying to make a snippet that takes the selected text and puts it into a tag ID. I can do it with a single word, but if the selection contains multiple words, I was to replace the spaces in the selection with hyphens before inserting as the ID. This is not working:

<content><![CDATA[ <a id="$SELECTION/\s/-/g"/>$SELECTION ]]></content>

For that matter, how would I also transform the selection to lowercase? What I am looking for is to select something like “Foo Bar” and get Foo Bar

0 Likes

Regex capture groups in snippets
Chained (Piped?) Snippet REGEX substitutions?
Regex support -- doesn't ST2 use the Boost library?
#2

I also need this functionality, so I’ll bump your post. :question:

I’m rusty with my regex but I’m guessing that it would be an easier fix in Perl or some other scripting language.
In Ruby, you could just use the downcase method. Foo-Bar.downcase would render “foo-bar”

0 Likes

#3

Thanks. I know several ways I could probably accomplish it, but I was just trying to use the syntax here:

http://sublimetext.info/docs/en/extensibility/snippets.html

But I was wondering if anyone knows why this example is not working.

0 Likes

#4

This will get you lowercase:

<snippet> <content><![CDATA[ <a id="${SELECTION/(.)/\L\1\E/g}"/>$SELECTION ]]></content> </snippet>

And this will get you dashes:

<snippet> <content><![CDATA[ <a id="${SELECTION/\s/-/g}"/>$SELECTION ]]></content> </snippet>
Unfortunately I don’t think it’s possible to do both at once. A nested regex doesn’t work, and it isn’t possible to assign variables.

This seems like the best solution:

<snippet> <content><![CDATA[ <a id="${1:${SELECTION/\s/-/g}}"/>$SELECTION ]]></content> </snippet>
That will leave the id section selected. Then just use CTRL+K, CTRL+L command to convert to lowercase.

0 Likes

#5
<a id="${SELECTION/([a-zA-Z]+)(\s?)/?1:\L$1(?2:-)\E/g}"/>$SELECTION

seems to work, although I’m testing it with $TM_CURRENT_LINE rather than selection.

I think it needs to be slightly more complex:

<a id="${SELECTION/([a-zA-Z]+)(?:(\s+?)|\b)/?1:\L$1(?2:-)\E/g}"/>$SELECTION
0 Likes

#6

Andrew, can you explain your second example a bit? Specifically the ?1: syntax; it’s as if you’re doing conditional substitution. I didn’t know that was possible, and I’d like to know more!

0 Likes

#7

Hello nick.

<a id="${SELECTION/([a-zA-Z]+)(?:(\s+?)|\b)/?1:\L$1(?2:-)\E/g}"/>$SELECTION

([a-zA-Z]+) captures one or more letters into group 1, provided they are also followed by space(s) or a word-break.
(?:(\s+?)|\b) is a non-capturing group, but if there are one or more spaces these *are *captured into a group, 2.

The ? following \s+ is necessary to create a non-greedy capture, otherwise the ‘g’ modifier will possibly force a capture of the whole line in one go!

?1: is a conditional, which says ‘if anything was captured in group 1’, insert this…
(?2:-) is a nested-conditional, and it will be ignored if there was no capture for group 2.

(?2:-:Doh) would (two colons : ) extend the conditional to say: “if group 2 was captured, insert a hyphen, otherwise insert ‘Doh’”.

Andy.

PS I didn’t know there was any such thing as a ‘nested conditional’ either - I just tried it :laughing:

0 Likes

#8

[quote=“agibsonsw”]Hello nick.

<a id="${SELECTION/([a-zA-Z]+)(?:(\s+?)|\b)/?1:\L$1(?2:-)\E/g}"/>$SELECTION

[/quote]

What’s that \E switch?

0 Likes

#9

@handycam

\L means “lowercase til \E”, so \E means “end case-modification”.

0 Likes

#10

How get first letter?

${1/(\w)(\w+)/\L\1/g}

But get small error!

0 Likes

#11

This was very helpful! I was looking for a way to automatically generate the cHeader file #ifndef / #ifdef stuff using the filename and starting with the info above I was able to end up with

#ifndef INCLUDED_${TM_FILENAME/([a-zA-Z]+)(?:(\.+?)|\b)/?1:\U$1(?2:_)\E/g}
#define INCLUDED_${TM_FILENAME/([a-zA-Z]+)(?:(\.+?)|\b)/?1:\U$1(?2:_)\E/g}

#endif

which, if the filename is myfile.h gives

#ifndef INCLUDED_MYFILE_H
#define INCLUDED_MYFILE_H

#endif

Then I went crazy and created this snippet

<snippet>
<!--
$1 == package
$2 == class
$3 == constructor arguments
$10 == decide if purpose/example exists. backspace if you don't want it
$11 == purpose
$12 == decide if example exists. backspace if you don't want it.
$13 == example

$0 == end point == class parameters
-->
    <content>
<![CDATA[
// package $1
// $TM_FILENAME

#ifndef INCLUDED_${1/([a-zA-Z]+)(?:(\.+?)|\b)/?1:\U$1(?2:_)\E/g}_${TM_FILENAME/([a-zA-Z]+)(?:(\.+?)|\b)/?1:\U$1(?2:_)\E/g}
#define INCLUDED_${1/([a-zA-Z]+)(?:(\.+?)|\b)/?1:\U$1(?2:_)\E/g}_${TM_FILENAME/([a-zA-Z]+)(?:(\.+?)|\b)/?1:\U$1(?2:_)\E/g}

#include <string>

namespace coderascal \{
namespace ${1:package} \{

// Class: ${2:${TM_FILENAME/([a-zA-Z]+)(?:(\.t?)|\b).h/?1:\u$1(?2:_T)/g}}
// Author: Dennis Gove (coderascal)
${10://
// Purpose: 
//  ${11:Don't forget to fill in your purpose for class $2}
${12://
// Example:
//  ${13:Examples are really (really) (super really) helpful. Come on. Do it.}}
}

class $2 \{
    
public:
    $2($0);
    $2(const $2& orig);
    ~$2();

private:

\} // end class

\} // namespace $1
\} // namespace coderascal

#endif
]]>
    </content>
    <tabTrigger>newh</tabTrigger> -->
</snippet>
0 Likes