1

I'm having trouble with this regex. (https://regex101.com/r/vQLlyY/1)

My pattern is working and is:

(?<=Property: )(.*?)(?= \(Contact)|(?<=Property: )(.*?)(?= - )

You'll see in the link that the property text is extracted in both these strings:

Property: This is the property (Contact - Warren) 
Property: This is another property - Warren

In my code, this pattern is stored like this:

$this->rex["property"][2] = '/(?<=Property: )(.*?)(?= \(Contact)|(?<=Property: )(.*?)(?= - )/s'

Then, it is extracted like this:

foreach ($this->rex as $key => $value ) {
    if (isset($value[$provider])) {
        preg_match_all($value[$provider], $emailtext, $matches);
        if (!empty($matches[1][0])) {
            $emaildetails[$key] = trim(preg_replace("/\r|\n/", "", $matches[1][0]));
        } else {
            $emaildetails[$key] = "";
        }
    }
}

In this example, $provider = 2

My problem I'm sure is with the blackslash because I can't get this code to pickup the (Contact part of the pattern where I need to escape the bracket. I know the code works because I have many other patterns in use. Also, this works for the property text if the pattern is stored like this:

$this->rex["property"][2] = '/(?<=Property: )(.*?)(?= - )/s

So, am I storing the pattern correctly with the escaped bracket, or is that even my problem? Thanks in advance!

Warren
  • 1,984
  • 3
  • 29
  • 60
  • Can you clarify if you're looking to capture "Contact" or just use it for matching? – Adam Mazzarella Mar 07 '17 at 01:54
  • Just matching - I will have `(Contact` following the property – Warren Mar 07 '17 at 01:59
  • Sorry, I'm still trying to understand the end result you're looking for. I wrapped your example code in this editor: http://sandbox.onlinephpfunctions.com/code/6a566fb5a0c6789d75a5fca24e4a6518cb1af561. Please update your answer with what you'd expect print_r to output. – Adam Mazzarella Mar 07 '17 at 02:20
  • @AdamMazzarella thanks - you've helped me see my problem. Have a look at http://sandbox.onlinephpfunctions.com/code/10fa078f8422228bec1674b19a1ad257058d47c4 - I have removed first string to find which now makes `$matches[1][0]` empty. Is there a way I can have `pattern1|pattern2` act as one and not place their results in corresponding groups? – Warren Mar 07 '17 at 03:01
  • Yes, I believe I know what you're looking for is a non-capture group. I slightly adjusted your regex to omit the positive lookaheads and instead use a non-capture group: https://regex101.com/r/vQLlyY/2. This will always return the element you're looking for (in this instance, at least) in index 1. – Adam Mazzarella Mar 07 '17 at 03:10
  • Fantastic! Please post an answer and I will accept. Basically, my `$matches[1][0]` was empty when the second pattern was being used and your pattern change is the fix :) – Warren Mar 07 '17 at 03:15

1 Answers1

0

Because you're using separate capture groups, the different paths are ending up in different match indexes. For instance, the first line (the Contact - Warren one) is storing the match result in index 1, where the second line has an empty string in index 1 and the match result you're looking for in index 2.

To solve this issue, you can use non-capture groups or you can rewrite your expression to use positive lookaheads. The benefits of the former include allowing for quantifiers. The benefits of the latter include not having the entire match result end up in your 0 match index.

Example of non-capture group: (?<=Property: )(.*?)\s*(?:\(Contact|- ) https://regex101.com/r/vQLlyY/2.

Example of positive-lookahead: (?<=Property: )(.*?)(?= \(Contact| - ) https://regex101.com/r/vQLlyY/3.

Adam Mazzarella
  • 763
  • 1
  • 7
  • 14
  • Please, insert the code instead of link only. This answer will become completly useless if the links are broken! – Toto Mar 07 '17 at 09:24