user10796008
user10796008

Reputation:

Regex comma as optional character

I have this regex that I made:

/\$([A-Za-z0-9\-\_ ]+)(\,?)/gi

I need to convert the following senteces:

$a, $b, $c, $hi = "", $na

Into this:

$a = NULL, $b = NULL, $c = NULL, $hi = "", $na = NULL

But I get this instead of the example above:

$a = NULL, $b = NULL, $c = NULL, $hi = "", $na

I'm using this to replace the values:

$$$1 = NULL$2

As you can see, if there isn't a comma, it won't work.

Hope you guys can help me.

Update: I just need to ignore it if it has "=" and a value: For example, I have to convert this:

$a, $a, $a
$a, $a = '', $a
$a
$a,
$a = ''
$a = '',
$a = '', $a

Into this

$a = NULL, $a = NULL, $a = NULL
$a = NULL, $a = '', $a = NULL
$a = NULL
$a = NULL,
$a = ''
$a = '',
$a = '', $a = NULL

The '' can be also NULL, "" and integer values.

Upvotes: 3

Views: 903

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110725

Since the desired result for the seven-line example string given in the question is just a literal, you don't need any code; just write it down. I suspect, however, that that is just an example of a broader, unstated question. How are we to guess what that question is from a single example? I will make a guess, but it's only a guess. You need to edit your question to state the question for which you have given an example. My guess follows.

Substrings to be modified begin with a dollar sign followed by one or more lower case letters followed by a comma or the end of a line in the string.

I wish to replace each substring to be modified, "$xx" with "$xx = NULL", where "xx" denotes any string of one or more lowercase letters.

Substrings to be modified can be identified with the regex

/\$[a-z]+(?=,|$)/

where (?=,|$) is a positive lookahead that requires the match to be followed by a comma or the end of a line ($) in the string.

Notice how this regex follows easily from a precise statement of the question.

I don't know Javascript, but in Ruby the substitution could be done as follows. If str is a given (possibly multi-line) string, the desired string can be obtained as follows:

str.gsub(/\$[a-z]+(?=,|$)/) { |s| "#{s} = NULL" } 

I confirmed this produces the desired result for the seven-line example string in the question.

I assume this can be translated to Javascript quite easily.

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627082

You may use

/\$([\w -]+)(?!\w|,?\s*=)(,?)/g

See the regex demo.

Note that [A-Za-z0-9_] = \w, thus the regex pattern can be shortened as shown above.

The (?!\w|,?\s*=) part is the main difference here: it makes sure there is no word char or an optional , followed with 0+ whitespaces and then = immediately after matching the Group 1 pattern, [\w -]+.

See the JS demo:

const texts = ['$a, $a, $a', "$a, $a = '', $a", '$a', '$a,', "$a = ''", "$a = '',", "$a = '', $a", '$a, $b, $c, $hi = "", $na'];
const regex = /\$([\w -]+)(?!\w|,?\s*=)(,?)/g;
for (let s of texts) {
  console.log("`" + s + "` => `" + s.replace(regex, '$1 = NULL$2') + "`")
}

Upvotes: 0

Enlico
Enlico

Reputation: 28460

Update 2

Actually you can use my original regexp, if you edit it using the proper flags:

/(?<=\$[A-Za-z0-9\-\_ ]+)(?=(?:,|$))/gmi

the m flag here is telling $ to match not only the absolute end of the input string (which is the EOL of the last line), but also the end of each line, which I could match with \n in the previous update, where I did not use the m flag. (The ^ metacharacter has a similar treatment.)

Update

Since after a while you came up with the news (that I should have expected, actually, so it's my fault) that the input file is multiline you need the following variation, which looks ahead for one of three possible things, , and $, as in my original answer, as well as a \n which is an EOL, for all the lines but the last:

/(?<=\$[A-Za-z0-9\-\_ ]+)(?=(?:,|\n|$))/gi

Original answer

You can use the following regex to detect the positions where you want to insert = NULL:

/(?<=\$[A-Za-z0-9\-\_ ]+)(?=(?:,|$))/gi

As I have used a lookbehind and a lookahead to find the position, the whole regex actually matches no text, but just a position, so you don't need to refer to anything in the substitution, which only needs to be = NULL. You can see it in action here.

More in detail

  • (?<=regex) matches the position (a zero-length match) at the end of the text matched by regex, so in the specific example it matches just after $a, $b, ...
  • (?=regex) matches at the position at the beginning of the text matched by regex, so in the specific example it matches just before , or $ (EOL), which are the two alternatives separated by |.
  • (?:…) is just a non-capturing version of (…).

Upvotes: 0

Related Questions