Mary N
Mary N

Reputation: 117

JavaScript regex to match the very precise number of the same characters

String example:

~~333~~

I need to get everything inbetween

~~

Regex that works:

/^(~{2})(.*?)(~{2})$/gm

But it also gets this string:

~~~333~~~

and also this:

~~~~333~~~~

What regex will get only the first one?

Upvotes: 3

Views: 105

Answers (6)

Mukesh Movaliya
Mukesh Movaliya

Reputation: 41

You can try the below code. this is to remove all special characters and return text and number value only :)


/[^a-zA-Z ]/g

var str = "~~333~~";
str.replace(/[^a-zA-Z ]/g, "");







Upvotes: 0

The fourth bird
The fourth bird

Reputation: 163362

As you used anchors in your current pattern with (.*?) to match anything in between, and you are using JavaScript in an environment that supports a lookbehind assertion, you can use a single capture group to get the desired value:

^~~(?!~)(.*)~(?<!~.)~$

Explanation

  • ^ Start of string
  • ~~ Match literally
  • (?!~) Negative lookahead, assert not a ~ directly to the right of the current position
  • (.*) Capture group 1, match any character 0 or more times
  • ~(?<!~.) Match the first ~ and assert that there is not a ~ directly to the left of the current position
  • ~ Match the second ~
  • $ End of string

See a regex101 demo.

const regex = /^~~(?!~)(.*)~(?<!~.)~$/;
[
  "~~333~~",
  "~~this is ~~~~~ a test ~~ test~~",
  "~~~333~~~",
  "~~~~333~~~~",
  "~~~this is ~ a test ~~ test~~test~~"
].forEach(s => {
  const m = s.match(regex);
  if (m) console.log(m[1]);
});

Some other variations

If you want to capture 1 or more digits in between:

^~~(\d+)~~$

regex101 demo

If you want to capture multiple occurrences without overlap:

(?<!~)~~(?!~)(.*?)~(?<!~.)~(?!~)

regex101 demo

If you want to capture multiple occurrences with overlap:

(?<!~)~~(?!~)(.*?)(?=~(?<!~.)~(?!~))

regex101 demo

Upvotes: 0

SaSkY
SaSkY

Reputation: 1086

Try this:

^~~[^~\r\n]+~~$

^ match the start of the line.

~~ match two literal ~.

[^~\r\n]+ match one or more character that is not ~ because we don't want to cross the two closing ~~, and also not \r or \n because we also don't want to cross newline characters.

~~ match two literal ~.

$ match the end of the line.

See regex demo.

Upvotes: 1

Biswajit Sharma
Biswajit Sharma

Reputation: 172

The below regex will match for exact two '~' in beginning and at last. And any string between those.

/^(~{2})([^~]*)(~{2})$

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521409

You could use a lookaround approach on both ends to ensure that tilde does not precede or follow the ~~ markers.

var input = "~~333~~ ~~~444~~~ ~~~~5555~~~~";
var matches = input.match(/(?:^|[^~])~~([^~]+)~~(?!~)/g);
console.log(matches);

Upvotes: 1

Nasser Kessas
Nasser Kessas

Reputation: 361

The reason your regex is matching the latter two test cases is because of your wildcard character . is picking up the inner ~s. To fix this, and make it only match numbers you could do this:

/^~{2}([0-9]*)~{2}$/gm

If you want to catch other characters as well as long as they ae not ~ you could match all characters excluding the ~ character like this:

^~{2}([^~]*)~{2}$

Both of these only match the first test case ~~333~~ and not the others.

Upvotes: 3

Related Questions