0

I have a string that is composed of different elements and I need to separate them at another tag in the string.

I used .split() and .pop() which worked great if there is only one element.

function getText(fullText, type) {

    var partial = fullText.split('*' + type + '*').pop().split('*/' + type + '*')[0] || 'unknown';
    return partial;
}

var str = "*a*Substring A*/a**b*Substring B*/b**c*Substring C*/c*"

getText(str, a)  // returns 'Substring A'

However, I have now encountered multiple elements and in this case it only returns the last element.


var str = "*a*Substring A*/a**b*Substring B1*/b**b*Substring B2*/b*"

getText(str, b)  // returns 'Substring B2'

How do I get an array with all the substrings between those tags?

5 Answers5

2

function getText(fullText, type) {
    let re = `\\*${type}\\*(.*?)\\*/${type}\\*`;
    return fullText
      .match(new RegExp(re, 'g'))
      .map(str => str.match(new RegExp(re))[1]);
}

var str = "*a*Substring A*/a* woah *a*Substring A 2*/a*"

x = getText(str, 'a') 

console.log(x)
junvar
  • 11,151
  • 2
  • 30
  • 46
  • RegExp is nice for this solution +1. – Maheer Ali Apr 26 '19 at 15:23
  • this is elegant solution but i'm using jsx with indesign to be precise and it seems like that doesn't support es6s map since it returns 'Error string: > does not have a value' can i do this any differently? – Gabriel Roda Eugen Bach Apr 27 '19 at 11:05
  • `map` is just syntax sugar for a traditional for loop. You could replace it as such. e.g. `for (let i = 0; i < fullText.length; i++) fullText[i] = str.match(...);` – junvar Apr 27 '19 at 17:16
1

You can use shift() to remove first element and then use map()

function getText(fullText, type) {

    var partial = fullText.split('*' + type + '*') 
    partial.shift();
    for(let i = 0;i<partial.length;i++){
      partial[i] = partial[i].split('*/' + type + '*')[0]
    }
    return partial
}

var str = "*a*Substring A*/a**b*Substring B1*/b**b*Substring B2*/b*"

console.log(getText(str, 'b'))
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
1

The reason why you're getting the last element is because you're using pop() which just returns the last element in array:

The pop() method removes the last element from an array and returns that element. This method changes the length of the array.

You can read more about it on here website

Ehtesham Z
  • 102
  • 10
1

Here's one way to do it.

function getText(fullText, type) {
    var typeStr = "\*" + type + "\*";
    return fullText
        .split('/')
        .filter(item=>item.match(typeStr.replace(/\*/g, '\\*')))
        .map(item=>item
            .substr(item.indexOf(typeStr) + typeStr.length)
            .replace(/\*$/, ''));
}

var str = "*a*Substring A*/a**b*Substring B*/b**c*Substring C*/c*"

console.log(getText(str, 'a'));  // returns 'Substring A'

var str = "*a*Substring A*/a**b*Substring B1*/b**b*Substring B2*/b*"

console.log(getText(str, 'b'));  // returns 'Substring B2'

Explaining:

// this creates a str with the type to be searched
var typeStr = "\*" + type + "\*";
return fullText
    // this splits all elements in your string
    .split('/')
    // this leaves only elements that match type...
    .filter(item=>item.match(
        // using a regex created with the typeStr created above
        // replace escape the * char to make regex work
        typeStr.replace(/\*/g, '\\*')))
    // now with the remaining parts, alter them as follows...        
    .map(item=>item
        // remove everything before type and type itself
        .substr(item.indexOf(typeStr) + typeStr.length)
        // remove last * char
        .replace(/\*$/, ''));

EDIT

Reading @junvar's answer I noticed a pattern that I haven't noticed when I answered. That if you substitute * by < or > you have a XML pattern. So it seems to me that the OP has replaced < and > by * in order to mask this is XML parsing. If it is a XML parse, please read the most famous answer in SO:

https://stackoverflow.com/a/1732454/2752520

JUST DON'T PARSE XML WITH REGEX.

Nelson Teixeira
  • 6,297
  • 5
  • 36
  • 73
1

Using pop() returns the last element in an array(the array that is created when you do your first split)

try:

function getText(fullText, type) {
        var partial = fullText.split('*' + type + '*');
        var result = [];
            $.each(partial, function(i, item) {
                 var split = item.split('*/' + type + '*');
                 if (split.length > 1) {
                      result.push(split[0]);
                 }
            });
             return result;
        }
        var str = "*a*Substring A*/a**b*Substring B1*/b**b*Substring B2*/b*";
        console.log(getText(str, 'b'));
Nelson Teixeira
  • 6,297
  • 5
  • 36
  • 73