0

I want to remove substrings from a string. These substrings are always between whitespaces and contain either push or pull.

Let's say I have the following string:

col-md-4 col-sm-6 col-md-pull-6 col-sm-push-4

How would I get the following (using PHP preg_replace)?

col-md-4 col-sm-6
0

3 Answers 3

3

You can do it like this:

$result = preg_replace('~(?:\s*+\S*pu(?:ll|sh)\S*)+~', '', $str);

pattern details:

~                # pattern delimiter
(?:              # open a non capturing group
    \s*+         # zero or more whitespaces (possessive)
    \S*          # zero or more non-whitespaces
    pu(?:ll|sh)  # push or pull
    \S*
)+               # repeat the non capturing group (1 or more)
~

Note: if the string begins with "push" or "pull", this pattern may let a leading whitespace, in this case, use rtrim to remove it.

Depending how looks your string, this variant that unrools the loop (?:[^p\s]+|p+(?!u(?:ll|sh)))*+ (that replaces more explicitly \S*) may be more performant:

(?:\s*+[^p\s]*+(?:p+(?!u(?:ll|sh))[^p\s]*)*+pu(?:ll|sh)\S*)+

about possessive quantifiers and lookarounds

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

2 Comments

pu(?:ll|sh) is this better than push|pull? i mean performance wise?
@vks: Theorically yes, because you don't have to parse pu two times in the worst case, so you have a small gain.
1

It also removes the spaces which exists before the sub-strings.

\h+\S*\b(?:push|pull)\b\S*|^\S*\b(?:push|pull)\b\S*\h+

Code:

$re = "/\\h+\\S*\\b(?:push|pull)\\b\\S*|^\\S*\\b(?:push|pull)\\b\\S*\\h+/m";
$str = "col-md-4 col-sm-6 col-md-pull-6 col-sm-pull-4\ncol-md-pull-6 foo bar";
$subst = "";

$result = preg_replace($re, $subst, $str);

DEMO

Comments

1
[^ ]*(?:push|pull)[^ ]*

Try this.Replace by empty string.See demo.

or

\s*[^\s]*(?:push|pull)[^\s]*

https://regex101.com/r/aI4rA5/7

$re = "/[^ ]*(?:push|pull)[^ ]*/m";
$str = "col-md-4 col-sm-6 col-md-pull-6 col-sm-pull-4";
$subst = "";

$result = preg_replace($re, $subst, $str);

4 Comments

Thanks, that does the trick! I couldn't quite work out how to select the entire word instead of just push or pull. You used the * for that, right?
@CasCornelissen we selected non space charactes then a push or pull then non space characters.* makes sure non space characters can be from 0 to as many as can`.
Right. Couldn't we use \s to also match other newline characters?
@CasCornelissen yes we can .\s will match [ \n\r\t].Added to answer

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.