SAz
SAz

Reputation: 365

Only capture `character` when preceded/succeeded by `character`

RegEx: /@{0,1}\s*x(.*?)x\s*@{0,1}/

The syntax I'm trying to force is xSomethingx and @xSomethingx@ where spaces are allowed within the @'s but not captured when there's no @'s.

Should match:

@ xSomethingx @ => @ xSomethingx @

. xSomethingx . => xSomethingx

What I tried so far: I've tried quite a few looksaheads and lookbehinds both positive and negative but I can only get it not to match whereas I don't want to capture spaces in that certain situation. I've also played around a bit with non-capturing groups.

Any pointers here? Can clarify more if need be.

Upvotes: 0

Views: 87

Answers (3)

mickmackusa
mickmackusa

Reputation: 48100

Here is a new best answer/pattern for you: /(?:@ *)?x.*x(?: *@)?/

This processes your string nearly twice as fast as Sahil's because his pattern makes the mistake of using pipes and a needless capture group. You will see that I have used a greedy quantifier on the dot (like Eduardo) because if there is an x in the in the substring, then the pattern will not capture the entire intended string -- this is a potential failure in Sahil's pattern.

Pattern Demo (insert Sahil's pattern to see how it fails to fully match one of the strings.)

However, I would like to point out that all of the answers on this page are failing to validate that a captured string ends as it begins. I mean, look at my regex demo, @xsome@thingx doesn't end with @ but it does start with it. To identify these occurrences properly, a more extensive pattern must be designed. If this is a concern for you / your project, then you should clarify this in your question so that the answers can be updated as needed.

Upvotes: 0

Eduardo Escobar
Eduardo Escobar

Reputation: 3389

This one could also work for you:

(?:@\s*)?x(?:.*)x(?:\s*@)?

-

'@         xSomethingx  @'                  ; // @         xSomethingx  @
'.            xSomethingx                 .'; // xSomethingx

It's a little different than Sahil Gulati's regex, but it will basically perform the same match.

Upvotes: 2

Sahil Gulati
Sahil Gulati

Reputation: 15141

Regex demo

PHP code demo

Regex: (?:@\s*|)x(?:.*?)x(?:\s*@|)

<?php
$pattern="/(?:@\s*|)x(?:.*?)x(?:\s*@|)/";
preg_match($pattern, "@xsomethingx@",$matches1);
preg_match($pattern, "@         xSomethingx  @",$matches2);
preg_match($pattern, ".            xSomethingx                 .",$matches3);
print_r($matches1);
print_r($matches2);
print_r($matches3);

Output:

Array
(
    [0] => @xsomethingx@
)
Array
(
    [0] => @         xSomethingx  @
)
Array
(
    [0] => xSomethingx
)

Upvotes: 1

Related Questions