preg_replace ўставіць значэнне па змаўчанні, калі апушчана

Я спрабую працаваць на некаторых рэгулярных выразаў для preg_replace, што б ўставіць ключ па змаўчанні = «значэнне», калі ён не ў тэме.

Вось што ў мяне ёсць:

$pattern = '/\[section([^\]]+)(?!type)\]/i';
$replacement = '[section$1 type="wrapper"]';

Я хачу, каб гэта ўключыць:

[section title="This is the title"]

у:

[section title="This is the title" type="wrapper"]

але калі ёсць значэнне, я не хачу, каб адпавядаць. Гэта азначае, што:

[section title="This is the title" type="full"]

застанецца такой жа.

Я выкарыстоўваю адмоўны прадпрагляд няправільна. Першая частка заўсёды будзе адпавядаць і (тып ?!) Становіцца недарэчным. Я не ўпэўнены, як змясціць яго так, што ён будзе працаваць. Любыя ідэі?

4

7 адказы

$your_variable = str_replace('type="full" type="wrapper"]','type="full"]',preg_replace ( '/\[section([^\]]+)(?!type)\]/i' , '[section$1 type="wrapper"]' , $your_variable ));

see it in action here http://3v4l.org/6NB51

2
дададзена
Гэта крыху занадта літаральным я думаю, таму што я амаль упэўнены, што ОП мае іншы тыпы , акрамя поўны .
дададзена аўтар Jerry, крыніца
$your_variable = str_replace('type="full" type="wrapper"]','type="full"]',preg_replace ( '/\[section([^\]]+)(?!type)\]/i' , '[section$1 type="wrapper"]' , $your_variable ));

see it in action here http://3v4l.org/6NB51

2
дададзена
Гэта крыху занадта літаральным я думаю, таму што я амаль упэўнены, што ОП мае іншы тыпы , акрамя поўны .
дададзена аўтар Jerry, крыніца

Гэта павінна быць

/\[(?![^\]]*type)section([^\]]*)\]/i
   -------------         ------
         |                  |->your required data in group 1
         |->match further only if there is no type!

try it here

2
дададзена
Вы ўпэўненыя, што працуе?
дададзена аўтар Sharky, крыніца
+1 за правільны адказ і быць карысным ASCII мастак :)
дададзена аўтар Sharky, крыніца
Цяпер @Sharky упэўнены .. :)
дададзена аўтар Anirudha, крыніца

Вы можаце выкарыстоўваць гэта:

$pattern = '~\[section\b(?:[^t\]]++|t(?!ype="))*+\K]~';
$replacement = ' type="wrapper"]';

echo preg_replace($pattern, $replacement, $subject);
2
дададзена
@Jerry: вы маеце рацыю, я перапісаць яго.
дададзена аўтар Casimir et Hippolyte, крыніца
Добры трук з \ K
дададзена аўтар Jerry, крыніца
Пачакайце, чаму вы выдаляеце, што + ёсць? <�Код> * здаецца, каб прадухіліць яго форму працуе належным чынам у цяперашні час.
дададзена аўтар Jerry, крыніца
Я адчуў гэта, калі ты быў * і гэта не спрацавала. Я прыняў Anirudh, таму што ён патлумачыў гэта прыгожа і гэта бліжэй да фарматам я ў іншым месцы. Ваша рашэнне працуе добра.
дададзена аўтар eli, крыніца

Вы можаце выкарыстоўваць гэта:

$pattern = '~\[section\b(?:[^t\]]++|t(?!ype="))*+\K]~';
$replacement = ' type="wrapper"]';

echo preg_replace($pattern, $replacement, $subject);
2
дададзена
@Jerry: вы маеце рацыю, я перапісаць яго.
дададзена аўтар Casimir et Hippolyte, крыніца
Добры трук з \ K
дададзена аўтар Jerry, крыніца
Пачакайце, чаму вы выдаляеце, што + ёсць? <�Код> * здаецца, каб прадухіліць яго форму працуе належным чынам у цяперашні час.
дададзена аўтар Jerry, крыніца
Я адчуў гэта, калі ты быў * і гэта не спрацавала. Я прыняў Anirudh, таму што ён патлумачыў гэта прыгожа і гэта бліжэй да фарматам я ў іншым месцы. Ваша рашэнне працуе добра.
дададзена аўтар eli, крыніца

Я думаю, што вы збіраецеся пра гэта няправільным шляху. Асабіста я хацеў бы выкарыстаць preg_replace_callback , каб апрацаваць яго. Нешта накшталт:

$out = preg_replace_all(
  "(\\[section((\\s+\\w+=([\"'])(?:\\\\.|[^\\\\])*?\\3)*)\\s*\\])",
  function($m) use ($regex_attribute) {
    $attrs = array(
      "type"=>"wrapper",
     //you may define more defaults here
    );
    preg_match_all("(\\s+(\\w+)=([\"'])((?:\\\\.|[^\\\\])*?)\\2)",$m,$ma,PREG_SET_ORDER);
    foreach($ma as $a) {
      $attrs[$a[1]] = $a[3];
    }
    return//something - you can build your desired output tag using the attrs array
  }
);
1
дададзена
Проста таму, што гэта больш складаны, не азначае, што гэта не так добра. Зусім наадварот, гэта вельмі магутнае рашэнне.
дададзена аўтар Niet the Dark Absol, крыніца
Дзякуй за Ваш адказ. Тым не менш, ваша рашэнне здаецца занадта складаным і цяжка чытаць у параўнанні з Anirudh гадоў.
дададзена аўтар eli, крыніца

Я думаю, што вы збіраецеся пра гэта няправільным шляху. Асабіста я хацеў бы выкарыстаць preg_replace_callback , каб апрацаваць яго. Нешта накшталт:

$out = preg_replace_all(
  "(\\[section((\\s+\\w+=([\"'])(?:\\\\.|[^\\\\])*?\\3)*)\\s*\\])",
  function($m) use ($regex_attribute) {
    $attrs = array(
      "type"=>"wrapper",
     //you may define more defaults here
    );
    preg_match_all("(\\s+(\\w+)=([\"'])((?:\\\\.|[^\\\\])*?)\\2)",$m,$ma,PREG_SET_ORDER);
    foreach($ma as $a) {
      $attrs[$a[1]] = $a[3];
    }
    return//something - you can build your desired output tag using the attrs array
  }
);
1
дададзена
Проста таму, што гэта больш складаны, не азначае, што гэта не так добра. Зусім наадварот, гэта вельмі магутнае рашэнне.
дададзена аўтар Niet the Dark Absol, крыніца
Дзякуй за Ваш адказ. Тым не менш, ваша рашэнне здаецца занадта складаным і цяжка чытаць у параўнанні з Anirudh гадоў.
дададзена аўтар eli, крыніца