Emberfire
Emberfire

Reputation: 132

Match everything in quotes except specific pattern

Is there a regex way to match around a specific pattern in a string? For example, I might have the string "foo$(bar)baz" and I might want to match "foo and baz" but not match $(bar), since the last pattern (which is a macro in a string in my case and the expressions are used to color the matches in different colors in a custom language) will be matched later by a separate regex. Note that I want to match content exclusively in quotes and include the quotes in the match.

The use case is a custom programming language. This language can have string literals that contain macros (text surrounded by brackets and a dollar sign in front, like the jquery selectors).

Examples: "This is a $(macro)" "$(macro)This is also a macro literal" "This is a literal that does not have a macro and needs to be matched as well" "$(This is a string literal that only contains a macro so only the quotes need to be matched)"

And an example directly taken from the language: SPRINTF("$(Vendor)")

In these examples the values matched need to be everything except the $(...) part, because that part will be matched in turn by another expression. The matching is done so that the code highlighter I use can color the matches differently. Think of it like the code highlighting of javascript placeholders in strings surrounded by ` characters.

Edit: Changed SPRINTF("test$(Vendor)") to SPRINTF("$(Vendor)").

Upvotes: 0

Views: 71

Answers (1)

Poul Bak
Poul Bak

Reputation: 10929

Second attempt (should work in all cases):

I'm not sure which regex engine is used for Microsoft's Monaco editor, but here I'm using javascript regex:

/"((?!\$\([^)]*\)).)*(?=.*")|(?<=".*)(.(?<!\$\([^)]*\)))*"/g

The regex will return 2 matches, one before the macro and one after.

Explanation: " - match a quote "

( - start a group

(?!\$\([^)]*\)) - negative look ahead for $(...)

. - match any char

)* - repeat this group zero or more times

(?=.*") - look ahead for any characters and a quote

| - OR

(?<=".*) - look behind for a quote " and any char zero or more times

( - start a group

. - match any char

(?<!\$\([^)]*\)) - negative look behind for $(...)

)* - repeat this group zero or more times

" - match a quote "

The regex uses the global flag.

I have created a test case for you, you can see the result and play with it here: JSRegExpBuilder

Upvotes: 1

Related Questions