2

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;
2
  • 3
    Use a regex, Luke. Commented Jun 3, 2021 at 11:31
  • e.g. ^.+\((.+)\)$ Commented Jun 3, 2021 at 11:36

5 Answers 5

2

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 )

Sign up to request clarification or add additional context in comments.

Comments

1

Using a regex:

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

Comments

1

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

Comments

1

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]));

Comments

1

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]);
   }       
});

7 Comments

The most simple and efficient in my opinion.
Change * to + and make sure that you got a match before doing [1], because doing [1] on null will throw an error.
@CasimiretHippolyte it also requires a limit set of characters within the braces, when no such criteria was mentioned by the OP.
@some: It can be solved using: aArray.reduce((c,s) => { m=s.match(regex); return m ? [...c,m[1]] : c }, []);
@Alnitak: it isn't really a problem, it's easy to change a character class to whatever you want. The most important thing here is that the pattern starts directly with the literal parenthesis, and this without to try to check the begining of the string.
|

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.