【问题标题】:Match regex pattern that isn't within a bbcode tag匹配不在 bbcode 标记内的正则表达式模式
【发布时间】:2018-01-10 05:34:06
【问题描述】:

我正在尝试创建一个正则表达式模式,它将匹配以 @ 开头的字符串中的单词

解决这个初始问题的正则表达式是'~(@\w+)~'

代码的第二个要求是它还必须忽略出现在 [quote][/quote] 标记中的任何匹配项

失败的几个尝试是:

(?:[0-9]+|~(@\w+)~)(?![0-9a-z]*\[\/[a-z]+\])

/[quote[\s\]][\s\S]*?\/quote](*SKIP)(*F)|~(@\w+)~/i

示例:以下字符串应具有显示的数组输出:

$results = [];
$string = "@friends @john [quote]@and @jane[/quote] @doe";

//run regex match
preg_match_all('regex', $string, $results);

//dump results
var_dump($results[1]);

//results: array consisting of:
    [1]=>"@friends"
    [2]=>"@john"
    [3]=>"@doe

【问题讨论】:

  • 我认为从字符串中删除\[quote\].+?\[\/quote\] 然后通过第一个正则表达式查找很简单

标签: php regex


【解决方案1】:

您可以使用以下正则表达式(基于another related question):

'~(\[quote](?:(?1)|.)*?\[/quote])(*SKIP)(*F)|@\w+~s'

请参阅regex demo。正则表达式用于嵌套 [quote] 标签。

详情

  • (\[quote](?:(?1)|.)*?\[/quote])(*SKIP)(*F) - 匹配捕获括号内的模式,然后 (*SKIP)(*F) 使正则表达式引擎省略匹配的文本:
    • \[quote] - 文字 [quote] 字符串
    • (?:(?1)|.)*? - 整个第 1 组模式 ((?1)) 或任何字符 (.) 出现的任何 0+(但尽可能少)
    • \[/quote] - 文字 [/quote] 字符串
  • | - 或
  • @\w+ - @ 后跟 1+ 个单词字符。

PHP demo:

$results = [];
$string = "@friends @john [quote]@and @jane[/quote] @doe";
$rx = '~(\[quote\](?:(?1)|.)*?\[/quote])(*SKIP)(*F)|@\w+~s';
preg_match_all($rx, $string, $results);
print_r($results[0]);
// => Array ( [0] => @friends [1] => @john [2] => @doe )

【讨论】:

    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多