youngSkywalker
youngSkywalker

Reputation: 21

how can I ignore a variable string length between two known strings when splitting in Javascript?

I'm brand new to JavaScript an quite a novice to coding in general, but I'm trying to self teach myself as much as possible.

I am trying to extract data from a variable string. The original string is in the following format:

CAMERA NAME(NUM):   North West Rd(D1) 
CAMERA NAME(NUM):   Even Longer Camera Name(D2) 
CAMERA NAME(NUM):   Cam13(D13)

All I want is the string within the final brackets. I was hoping to have a split function which I could say something along the lines of

str.split(CAMERA NAME(NUM):    **variable Characters and length** (,);

But I'm unsure how to account for the variable text and length in between (NUM): and (

I'd be very grateful for any suggestion, Thanks!

P.s - I'm currently using this method which works, but I'd like to know how to account for variable strings for future projects, as this will almost certainly come up again.

Thank you. Luke

var txt = msg.payload;
var array = [];
var newTxt = txt.split('(');
//node.warn(newTxt);
for (var i = 1; i < newTxt.length; i++) {
   array.push(newTxt[i].split(')')[0]);
}
//node.warn(array[1]);
msg.payload = array[1];
return msg;

Upvotes: 2

Views: 163

Answers (5)

alexP
alexP

Reputation: 3765

Use regex:

const aCamera = [
  "CAMERA NAME(NUM):   North West Rd(D1)",
  "CAMERA NAME(NUM):   Even Longer Camera Name(D2)",
  "CAMERA NAME(NUM):   Cam13(D13)"
];
const oRegex = /\(([A-Za-z0-9]+)\)$/;

aCamera.forEach(sCamName => {
   let aResult = sCamName.match(oRegex);
   if(aResult && aResult [1]){ //Check if there's a result
    console.log(aResult [1]);
   }       
});

Upvotes: 1

The fourth bird
The fourth bird

Reputation: 163267

As you mention there are 2 parts, you can match both of them making sure that they are there while capturing the last part in a group.

\([^()]+\):.*\(([^()]+)\)$
  • \([^()]+\): Match the part with the parenthesis ending with :
  • .* Optionally match any char (The variable part)
  • \(([^()]+)\) Match (, capture in group 1 any char except parenthesis, and match )
  • $ End of string

Regex demo

const regex = /\([^()]+\):.*\(([^()]+)\)$/gm;
const s = `CAMERA NAME(NUM):   North West Rd(D1)
CAMERA NAME(NUM):   Even Longer Camera Name(D2)
CAMERA NAME(NUM):   Cam13(D13)`;
console.log(Array.from(s.matchAll(regex), m => m[1]));

Upvotes: 1

julianpoemp
julianpoemp

Reputation: 2022

I would solve this using regex. You can do experiments with Regex using https://regexr.com/5uaag

// move all relevant information to groups
var regex = /([^\n()]+)\(([^()]+)\):\s*([^()]+)\(([^()]+)\)/g;

// ([^\n()]+): move all Chars that are not newlines or brakes in a group
//  \(([^()]+)\): move all chars wrapped in brakes to a group

var test = `CAMERA NAME(NUM):   North West Rd(D1)
CAMERA NAME(NUM):   Even Longer Camera Name(D2)
CAMERA NAME(NUM):   Cam13(D13)`;

var cameras = [];
var match = regex.exec(test);

while(match) {
  // attributes can be changes as you wish
  cameras.push({
    name: match[1],
    num: match[2],
    location: match[3],
    locationTag: match[4]
  });
  match = regex.exec(test);
}

console.log(cameras);
// now you can iterate the cameras array and read the information easily

Upvotes: 1

Alnitak
Alnitak

Reputation: 339786

Using a regex:

const val = 'CAMERA NAME(NUM):   Even Longer Camera Name(D2)';
const id = val.replace(/^.+\((.+)\)$/, '$1');

Upvotes: 1

ikiK
ikiK

Reputation: 6532

If your outcome is allways like your provided example you can do this with one liner:

let val = "CAMERA NAME(NUM):   North West Rd(D1)"
let res = val.split("(").pop().replace(")", "")
console.log(res)

let val = ["CAMERA NAME(NUM):   North West Rd(D1)",
  "CAMERA NAME(NUM):   Even Longer Camera Name(D2)",
  "CAMERA NAME(NUM):   Cam13(D13)"
]

val.forEach(i => {
  let res = i.split("(").pop().replace(")", "")
  console.log(res)
})

Split the string at (, take just last of array using pop(), and remove )

Upvotes: 2

Related Questions