I have a string below, and I want to extract the value of the headers inside my string, such as "Change Type" or "Change Summary".
I was thinking about using regex, but I'm not sure because it seems like regex is only used for validations.
" # Release Notes #
## Change Type ##
-[] Enhancement
-[x] Defect
## Change Summary ##
This Release is to fix a null pointer issue.
## Is this Active ##
-[x] Yes
-[] No
## Team ##
Jaguar Team
## Impacted Customer ##
-[x] Internal
-[] External "
How can I do this effectively? Can I use regex for this?
CodePudding user response:
We can use Regex with lookarounds to match our data.
const re = /(?<=(^|\n)## ).*?(?= ##(\n|$))/g;
const titles = `" # Release Notes #
## Change Type ##
-[] Enhancement
-[x] Defect
## Change Summary ##
This Release is to fix a null pointer issue.
## Is this Active ##
-[x] Yes
-[] No
## Team ##
Jaguar Team
## Impacted Customer ##
-[x] Internal
-[] External "
`.match(re);
console.log(titles);
Note this intentionally doesn't match ## Change Type ##
, as there is a space in front of it, nor # Release Notes #
for the same reason and because it only has one #
before and after it.
Regex Breakdown
(
?<=(^|\n) # match any text after a new line or beginning of string
## # match "##" followed by one or more spaces
)
.*? # match any text with greedy-prevention
(
?= ## # match any text before any one or more spaces and "##"
(\n|$) # match anything before a new line or end of string
)
Without regex
If you don't want to use regex because you got mad at it, offended it, or have any other (good) reason not to use it, here's the regex-free alternative.
const extract = input => {
let strs = input.split("\n"); // split the string line by line
return strs.map(i => {
// check if string matches criterion
if(i.startsWith("## ") && i.endsWith(" ##"))
return i.substring(3, i.length - 3); // remove "## " and " ##"
}).filter(o => !!o); // remove falsy values
};
console.log(extract(`" # Release Notes #
## Change Type ##
-[] Enhancement
-[x] Defect
## Change Summary ##
This Release is to fix a null pointer issue.
## Is this Active ##
-[x] Yes
-[] No
## Team ##
Jaguar Team
## Impacted Customer ##
-[x] Internal
-[] External "
`));
CodePudding user response:
You can get the headers with: /(?<=##). (?=##)/g
This pattern basically tells to match anything that is between two #.
Test here: https://regex101.com/r/F4HUIf/1
let input = `" # Release Notes #
## Change Type ##
-[] Enhancement
-[x] Defect
## Change Summary ##
This Release is to fix a null pointer issue.
## Is this Active ##
-[x] Yes
-[] No
## Team ##
Jaguar Team
## Impacted Customer ##
-[x] Internal
-[] External "`
let pattern = /(?<=##). (?=##)/g
input.match(pattern).forEach(e=>{
console.log(e.trim()) //using trim to remove extra white spaces
})
//Change Type
//Change Summary
//Is this Active
//Team
//Impacted Customer