1

i'm not quite good using regex and spend two days try to fixing this problem and of course searching solutions in stackoverflow but nothing solve my problem. and here's the problem.

score variable will increased by 1 using this code

@inc score

we capture the variable using this regex

inc: /^@inc (.*)$/

and this is the argument

if (match.inc) {
   section = this.addAttribute(match.inc[1] + '+=1', story, section, passage, isFirst, inputFilename, lineCount);
}

then i try to advanced it a little more to be like this

@inc score 15

and i alter the regex

inc: /^@inc (.*)( )(.\d*)$/

and that code work fine with this alteration

if (match.inc) {
   section = this.addAttribute(match.inc[1] + '+=' + match.inc[3], story, section, passage, isFirst, inputFilename, lineCount);
}

my question is, how the regex should be? if i want keep both working

@inc score          <----- will increase by 1

@inc score 100000   <----- will increase by number

and of course how the argument should be?

here's the actual code link line 197 and line 299

sorry for my bad english, not my mother language

2 Answers 2

1

I'm not entirely sure of the syntax you are using (but then, I'm not very used to javascript...), but here's a little snippet that should be able to give you some ideas:

var scores = ["@inc score", "@inc score 100"];

var re = /@inc score(?: (\d+))?/;

for (i = 0; i < scores.length; i++) {
    var inc = scores[i];

    if (result = inc.match(re)) {
        var addition = "+=" + (result[1] === undefined ? '1' : result[1]);
        alert(addition);
    }
}

jsfiddle demo

When the input is "@inc score", the result becomes +=1 and when it is "@inc score 1000", it becomes +=1000.

(?: (\d+))? in the regex matches an optional group containing 1 space and at least 1 digit. The digits are being captured and will be the second element of the resulting list when attempting a match. This element is what is being tested at the conditional/ternary operator.


EDIT: Oops, to use score as the variable to be increased, you can use the same concept, constructed slightly differently:

var scores = ["@inc score", "@inc score 1000", "@inc amount 1000"];

var re = /@inc (\S+)(?: (\d+))?/;

for (i = 0; i < scores.length; i++) {
    var inc = scores[i];

    if (result = inc.match(re)) {
        var addition = result[1] + "+=" + (result[2] === undefined ? '1' : result[2]);
        alert(addition);
    }
}

I guess in your own code, it should be like:

inc: /^@inc (\S+)(?: (\d+))?$/

and

if (match.inc) {
   section = this.addAttribute(match.inc[1] + '+=' + (match.inc[2] === undefined ? '1' : match.inc[2]), story, section, passage, isFirst, inputFilename, lineCount);
}
Sign up to request clarification or add additional context in comments.

2 Comments

the score variable is just example because user can use any string they want such as @inc goal, money, etc. here's the actual code link line 197 and line 299
@caberg Ok, I have amended the regex for the @inc string. And sorry, I'm not a javascript dev, but I have attempted inserting this logic in your code (answer edited).
1

I would use this regex ^@inc (.*?)(?:(\s)(\d+))?$

You can see it in action here https://regex101.com/r/dO6yN8/2.

In the first capturing group it captures everything until it sees a space (if it exists), which you wanted to be in the second capturing group for some reason, and then captures the numbers after that space in the third group. The space and numbers are optional however.

2 Comments

I think supporting multiple spaces is a good option ^@inc (.*?)(?:(\s+)(\d+))?$
i think this regex is good but again, how about the argument?. here's the actual code link line 197 and line 299 sorry for my noobness

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.