StuStirling
StuStirling

Reputation: 16231

Only Match String if Text Does Not Contain Another String

I have the following use case. I need a Regex pattern to only match a line, if part of the string does not contain a different string. Here is an example:

<androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"/>

So here I want to match android:layout_marginStart="12dp" so that I can replace with:

android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"

I have worked this one out and I can use the following regex to do it:

Find: (.*)android:layout_marginStart="(.*)" Replace: $1android:layout_marginStart="$2"\n$1android:layout_marginLeft="$2"

What I can't do is conditionally match. I do not want to match if this xml object already contains the android:layout_marginLeft attribute.

Upvotes: 0

Views: 156

Answers (1)

Quixrick
Quixrick

Reputation: 3200

In regex, if you want to check to make sure a string is not coming up after the part you wish to match, you can use a negative lookahead.

In this example, you want to match something, but only if the string layout_marginLeft is not coming up later. You can do that, but throwing layout_marginLeft into a negative lookahead, like this:

(?:(?!layout_marginLeft).)*

Now, when you combine that with what you actually want to match your regex would look something like this:

(android:layout_marginStart="(.*?)")(?:(?!layout_marginLeft).)*(?=/>)

And then your replacement string would look like this:

\1\n\t\tandroid:layout_marginLeft="\2"

So, the replacement stuff works the same way, it's just that you are telling it not to do a replacement on anything that already contains layout_marginLeft.

Here is a demo

Upvotes: 1

Related Questions