Regex: Open and close with the same character and allow more than one type

Asked

Viewed 220 times

2

It is possible to get a text between two characters that are equal, with the following conditions:

  • The opening character shall be the same as the closing character.
  • Allow more than one character type in opening/closing.

Simple example:

/("|')asdasd("|')/

Let me take "asdasd" and 'asdasd'

But he also takes "asdasd'

How to make when it is opened with ", allow to close only with "?

  • But { and } are not the same character if it were {asdasd{ would be easy. You need to create a function that compares the unicode. How many possible pairs will you use?

  • Yes really, it was just a bad example I used. What if the characters were " and '? - How the function you mentioned would work?

  • I don’t see why the example is bad, I easily imagine cases where this is useful. Regarding the question '/", you mean at the beginning you would have " and in the end ' or would it be the same at the beginning and end? (and you saw my question: "How many possible pairs will you use?")

  • I say bad example in order of simplicity to question. If at first it is ", should end with the same, and the same to '. Never starting with " and ending with '. I’ll use 5 pairs.

2 answers

2


You can use \1 to ensure the use of the same character as in a capture group.

Thus, define some "limiters" at the beginning of the string, and at the end use \1 to make sure you have the same:

var testes = [
  '!abba!', '?abba?', '"ab ba"', "'abba'", 'xabbax', '!eu vou falhar?'
];

function filtro(str) {
  var match = str.match(/([!?'"x])(.*)(\1)/);
  if (!match) return '';
  return match[2];
}

console.log(testes.map(filtro));

In cases where you want to use pairs of symbols to open and close a text region, such as {}, () or <> this could be done:

const testes = [
  '(abba)', '!eu vou falhar?', '{abba}', '<A>'
];
const separadores = ['{}', '\\(\\)', '<>'].map(char => {
  const abertura = char.slice(0, char.length / 2);
  const fecho = char.slice(char.length / 2);
  return `(${abertura})([^${fecho}]+)(${fecho})`
}).join('|');
console.log(separadores)
const regex = new RegExp(separadores);

function filtro(str) {

  var match = str.match(regex);
  match = match && match.filter(Boolean);
  if (!match) return '';
  return match[2];
}

console.log(testes.map(filtro));

  • 1

    Perfect use of group capture within the regex itself. I didn’t know it was possible this. Thank you.

  • 1

    Although the AP has validated, I came up with a question : how to work your example in a running text, I made a small change and see the result : https://regex101.com/r/OouWLx/4

  • @Magichat in this case of mixed text the solution has to be more complex. Either it separates everything first, or else also as ['{', '\\?', '"', 'x'].map(char => \(${char})([ ${char}]+)(${char})`). Join('|')` to generate the regex that would look like this: https://regex101.com/r/In0Ayw/1

  • Note that it still takes the string inside characters where its closure is the opening: {fsdfsdff{...

  • Surely there is confusion, where the understanding that Se no inicio for ", deve terminar com o mesmo be applied also in the case of {}[]()<>... I may be wrong, but I don’t think... Anyway I’m not testing your ability, but now I’m more sure the issue is unclear, and only the AP could clarify... Well re-reading again the question I believe Como fazer com que quando é aberto com {, permitir fechar apenas com } clarifies. Vlw man..

  • I edited the question, the answer still fits. But it would be interesting an example of when it is opened with { allow not himself at the end, but a different character in the case }, still being dynamic to allow more than one pair.

  • @Rafaelmafra added this option to the answer.

  • @Magichat added another variant to the answer, after the question was clarified.

Show 4 more comments

1

  • Thanks for the answer. This is a very static solution, and if instead of { and ( if more characters were used? Or even a range. It is impossible to list all.

  • @Rafaelmafra what I find interesting is to see how some people are good at giving information when it comes to explaining why such a solution does not suit you, but when asking the question has no such concern. In my view my answer perfectly meets what was asked. Instead of putting your comment, why not edit your question?

  • I edited the question to make it clearer. But that’s what I said, your solution is functional, but I wanted a dynamic way, as I use the groups @Sergio showed.

  • What groups? I think you’re confusing javascript with regex... E at the end the result of the js function shown is similar to what I did...

  • Group I speak is the data captured in parentheses.

  • I see you didn’t understand me....

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.