Using regex to match a line between two lines, excluding lines

Following the previous question in which I asked:

How can I use a regular expression to match text between two lines, where the two lines themselves are enclosed in two other lines with any amount of text between the inner and outer spanning lines?

I got this answer:

/outer-start.*?inner-start(.*?)inner-end.*?outer-end/

Now, I would like to know how to exclude certain lines from text between the outer span lines and the inner span lines.

For example, if I have this text:

external start some text internal start text-that-i-want internal end some text end

I would like “some text” and “some other text” not to contain the word “objectionable”.

In other words, this is normal:

external start some desired text internal start text-that-i-want internal end some more necessary text external end

But this is not normal:

outer-start some unwanted text inner start text-that-i-want inner end another unwanted text outer end

Or to clarify further, the expression between the outer and inner delimiters in the previous answer above should exclude the word "unwanted".

Is it easy to match with regular expressions?

+5
6

( ) .*? (?:(?!unwanted).)*?. ( (?:...) - , (?!...) - ).

, ( ) , , ( , , ), , , .

+5

, " ?" " ?". , . , , - .

, , , (: , ). , . , . , , , , .

+2

.*?

 ([^u]|u[^n]|un[^w]|unw[^a]|unwa[^n]|unwan[^t]|unwant[^e]|unwante[^d])*?

"" ; , , .

+1

, , Perl, , . - :

/outer-start(?:u(?!nwanted)|[^u])*?inner-start(.*?)inner-end.*?outer-end/

"" ( "u", "nwanted" ) ( "u" ). , "" .

, .;)

+1

. *? : (?! (. * . *))

?

0

Tola, , , . , , "regex-match pattern, ..."

, ( |), , , ... | , , 1. 1, , .

?

-, , unwanted outer-start inner-start. :

outer-start(?:(?!inner-start).)*?unwanted.*?outer-end

|. .

-, , unwanted inner-end outer-end. :

outer-start(?:(?!outer-end).)*?inner-end(?:(?!outer-end).)*?unwanted.*?outer-end

|. , , "" *? .

-, , . :

inner-start\s*(text-that-i-want)\s*inner-end

, :

(?xs)
outer-start(?:(?!inner-start).)*?unwanted.*?outer-end # dont want this
| # OR (also don't want that)
outer-start(?:(?!outer-end).)*?inner-end(?:(?!outer-end).)*?unwanted.*?outer-end
| # OR capture what we want
inner-start\s*(text-that-i-want)\s*inner-end

, 1 : , , .

In Perl and PCRE (used, for example, in PHP) you don’t even need to look at group 1: you can make the regular expression skip two blocks that we don’t need. The regular expression becomes:

(?xs)
(?: # non-capture group: the things we don't want
outer-start(?:(?!inner-start).)*?unwanted.*?outer-end # dont want this
| # OR (also don't want that)
outer-start(?:(?!outer-end).)*?inner-end(?:(?!outer-end).)*?unwanted.*?outer-end
)
(*SKIP)(*F) # we don't want this, so fail and skip
| # OR capture what we want
inner-start\s*\Ktext-that-i-want(?=\s*inner-end)

See the demo : it directly matches what you want.

This method is explained in detail in the question and article below.

Link

0
source

All Articles