SILENT
SILENT

Reputation: 4268

Regex that matches up string or end of line

I need a javascript regex that matches strings that start with # and end on either \n# or end of line (which ever comes first).

Samples - https://regex101.com/r/rpjPkl/4

For the following samples:

Sample 1: #always: test\n#asdf

Results: #always: test with groups always and test

Sample 2: #always: test\n#range: [0, 255]

Results: #always: test with groups always and test

and #range: [0, 255] with groups range and [0, 255]

I've tried (for hours...) various versions of the following:

#([a-z]+):(.+)((\\n#)|$)
#([a-z]+):((^\\n#)|$)+

Update 1:

The group results should separate out \n if its found. If its not possible to get above groups, at min, I need the following group results

Sample 1 expecting groups: #always: test

Sample 2 expecting groups: #always: test and #range: [0, 255]

Note that \n can exist as a group but can't included in the above groups.


Update 2

I'm providing a more exhaustive sample that should cover (hopefully) all scenarios.

Live sample link: https://regex101.com/r/rpjPkl/4 The answer must test against the Test String found in this link (same as below Sample 3).

Sample 3:

#always: line1\nline#2\n#range: [0, 255]\n#obj: { prop: '#a1',
prop2: 2 }\n#more: "where #2"

Expected matches / groups

Match 1: #always: line1\nline#2 Group 1: always Group 2: line1\nline#2

Match 2: #range: [0, 255] Group 1: range Group 2: [0, 255]

Match 3:

#obj: { prop: '#a1',
            prop2: 2 }

Group 1: obj Group 2:

{ prop: '#a1',
            prop2: 2 }

Match 4: #more: "where #2" Group 1: more Group 2: "where #2"

Upvotes: 0

Views: 90

Answers (1)

Ja͢ck
Ja͢ck

Reputation: 173562

Instead of trying to capture repeating patterns, you could perform an initial split on each sample by newline first, to make the matching easier.

const samples = [
  '#always: test\n#asdf',
  '#always: test\n#range: [0, 255]'
]

function foo(sample)
{
  // split first, and then iterate over each sentence
  return sample.split('\n').map(sentence => {
    // this expression is now very basic
    return sentence.match(/^#([a-z]+):\s*(.+)/)
    // empty matches yield null and will get filtered later
  }).filter(match => match !== null)
}

samples.forEach(sample => {
  console.log(foo(sample));
})

Upvotes: 1

Related Questions