0

I have the following code:

<?php
    $subject="something";
    $pattern="something";
    If(preg_match($pattern,$subject)){
        echo "Match is found";
    }else{
        echo "Match is not found";
    }
?>

If I have

$subject="apple is fruit and I love apple";

The main point being the string beginning with apple and ending with apple

Then what should be the pattern so that

match is found

is the output.

I know the pattern can be

"/^apple.*apple$/"

But I don't want to repeat the same word apple.

  • You don't want to repeat the substring `"apple"`? Put it in a variable: `$word = "apple";`, or use `sprintf` to build your pattern. – Casimir et Hippolyte Jun 09 '17 at 17:13
  • This cannot be the answer as then I have to repeat $word variable –  Jun 09 '17 at 17:14
  • 3
    I think you want something like this: ^(\w+)\b.*\b\1$ Basically, start with a word (\w+) and then a word boundary. Whatever is in the (\w+) must then be at the end, which is the \1 I'm not sure what the \1 syntax is in php, this is for Python. Maybe $1 ? – sniperd Jun 09 '17 at 17:15
  • You don't have to do it with `sprintf` – Casimir et Hippolyte Jun 09 '17 at 17:15
  • maybe try `/^apple((?!apple).)+apple$/m` – hanshenrik Jun 09 '17 at 17:18
  • you want to match all the string that starts with apple and ends with apple ??? – lotfio Jun 09 '17 at 17:19
  • i think he wants strings that start with apple, and ends with apple, but otherwise doesn't contain the word apple – hanshenrik Jun 09 '17 at 17:20
  • Maybe https://eval.in/814950 or it has to be 1 regex? – chris85 Jun 09 '17 at 17:20
  • 1
    I feel OP needs `"/^(apple).*(?1)$/s"` (due to *I don't want to repeat the same word apple.*) – Wiktor Stribiżew Jun 09 '17 at 17:21
  • @ForDev you are correct, but in middle it may or may not have apple, just the beginning and end should have apple –  Jun 09 '17 at 17:21
  • @cyano_learner if that's the case, then your current regex already does the job. – hanshenrik Jun 09 '17 at 17:23
  • @hanshenrik yeah it does, that's where my question is, that is there any other way to achieve the same by not repeating the word apple –  Jun 09 '17 at 17:24
  • @cyano_learner It may or may not have apple in the middle? I thought apple was not allowed in the middle? – chris85 Jun 09 '17 at 17:24
  • `$pattern = sprintf('/^%1$s.*%1$s$/', 'apple');` like this? – Casimir et Hippolyte Jun 09 '17 at 17:25
  • in that case, i think @WiktorStribiżew is correct (what a weird requirement though) – hanshenrik Jun 09 '17 at 17:25
  • @CasimiretHippolyte you are not getting me, here you are repeating %1$s but I am wondering if there is any shortcut where there is absolutely no repitetion –  Jun 09 '17 at 17:27
  • what could possibly require you not to repeat the word? are you in a code obfuscation contest? but i still think @WiktorStribiżew is correct. – hanshenrik Jun 09 '17 at 17:30
  • Yeah that's why I have voted him up? –  Jun 09 '17 at 17:31
  • Sorry, I am not sure if I should post that or not. I bet there is a dupe post, but cannot find it. – Wiktor Stribiżew Jun 09 '17 at 17:33
  • @WiktorStribiżew Is there an advantage to using recurse over backreference? – chris85 Jun 09 '17 at 17:40
  • 1
    @chris85: Only in case `apple` is in fact a placeholder for some other pattern, e.g. `<<[A-Z]{3}>>`. But not really sure, the question is rather weird. I just do not see any issue. Closing it as primarily opinion-based. – Wiktor Stribiżew Jun 09 '17 at 17:42
  • Actually I thought that repetetion means longer coding, so any shortcut if present is better, like in c language, rather than writing b=b+1 we write b++ –  Jun 09 '17 at 17:45
  • You just need a [backreference](https://stackoverflow.com/questions/2722472/can-you-use-back-references-in-the-pattern-part-of-a-regular-expression). Try: /^(\w+).*(\1)$/ – CDahn Jul 06 '17 at 00:44
  • It's super unclear to me why this extremely simple question garnered so much discussion. The question has been answered, it's customary to accept one of the answers or explain why the answers don't satisfy your question. – CDahn Jul 07 '17 at 01:42

1 Answers1

0

You just need a backreference. Try:

/^(\w+).*(\1)$/

The (\w+) captures the first word, no matter what it is, without having to specify "apple" as the word. The backreference, \1 tells the regex parser to substitute in whatever was captured in the first capture group. Using the magic of backtracking, the regex parser will figure out how to fit match the input symbols correctly to satisfy the backreference.

CDahn
  • 1,795
  • 12
  • 23