【问题标题】:Regular expression to match after first % and before last %在第一个 % 之后和最后一个 % 之前匹配的正则表达式
【发布时间】:2023-03-03 23:35:01
【问题描述】:

我需要一个正则表达式,它可以匹配以下字符串中“%”标记内的内容:

1) Bla bla bla %yada yada yada% bla bla.

即使表格是这样的:

2) Bla bla bla %yada yada yada% bla bla %yada #1 yada%

我认为/%([^%]*)%/ 可以,但在第二种情况下,它与第二部分 (%yada #1 yada%) 不匹配,仅与第一部分匹配。

即使“%”标记之间的子字符串包含“#1”之类的内容,表达式也必须匹配。提前谢谢你

问候

function replace($search, $replace, $subject, $link)
    {
        if (preg_match('/#[1-9]/', $search) == 1 && $link == null)
        {
            echo preg_replace($search, $replace, $subject);
        }
        if (preg_match('/%[a-zA-Z0-9# ]+%/', $search) == 1 && $link != null && $replace == null)
        {
            echo preg_replace('/%[a-zA-Z0-9# ]+%/', '<a href=$link>$1</a>', $subject, 1) . '<br>';
        }
    }

$string = 'bla bla #1 bla bla %bla bla% bla #2 %bla bla #3 bla%';
$newString = replace('/%[a-zA-Z0-9# ]+%/', null, $string, 'www.google.com');
echo $newString;
preg_match('/%[a-zA-Z0-9# ]+%/', $newString)); // 0 = no match

所以在第二次通话中我没有得到匹配。希望这会有所帮助。

【问题讨论】:

  • 您想将yada yada yada% bla bla %yada #1 yadayada yada yadayada #1 yada 与第二个测试匹配吗?
  • 您想要一个提取的子字符串,还是多个?考虑X%A%B%C%Y。您是想要拉出三个内部字符串ABC,还是只想拉出A%B%C?从您对其中一个答案的评论来看,您非常希望有三场比赛,以便您可以对每场比赛进行某种s/foo/bar/g 魔术。
  • @MaPePeR 第一次调用我的函数(在第二个示例中)它必须匹配“yada yada yada”。该函数会将“%”标记替换为:&lt;a href="link"&gt;yada yada yada&lt;/a&gt; 第二次我调用它时,它应该对“yada #1 yada”执行相同的操作。因此,当我第二次调用它时,它会将最后两个“%”剩余标记替换为:&lt;a href="another link"&gt;yada #1 yada&lt;/a&gt;
  • @Kapn0batai 编辑您的问题以添加代码的相关部分。
  • 您是否正在使用 Javascript 修改 html 文档?如果是这种情况,除了(未)损坏的正则表达式之外,您可能还有其他问题。通过将元素插入innerHTMLinnerHTML 将不再包含该字符串。

标签: php regex parsing html-parsing substitution


【解决方案1】:

%.*%

这将匹配

1) 一个 %

2) 任意数量的任意字符

3) 一个%

因为它会贪婪地匹配而不是懒惰地匹配,所以它会匹配最广泛的 %...%,而不是在第一个停止。

例如,它的惰性版本是 %.*?%(在 * 之后放 ? 使它变得惰性),它会在第一个而不是最后一个 % 之后关闭。

【讨论】:

    【解决方案2】:

    查看您对preg_match...的调用...第二个参数应该是$subject 而不是$search...

    另外,使用return 来实际返回一些东西,而不是echo

    【讨论】:

    • 我有一个函数,每次替换都会调用一次。所以,我调用了一次函数,它替换了第一个子字符串。我第二次调用它(第 3 个和第 4 个“%”标记仍在字符串中)它找不到匹配项。我认为这与标记内的“#1”有关。
    • 其实我不这么认为。我误读了他的例子(或者他改变了它?)。这不是解决方案。 @Kapn0batai 你能添加你的代码吗?我认为这会有所帮助。
    • 天哪!当这种情况发生时,我讨厌它。是的,这是某种丑陋的 php ad-hockery。
    • preg_match 仅标识我用作参数的字符串。这就是函数有两个“if”的原因。所以第二个参数是 $subject 因为我想知道,当函数被调用时,必须发生的替换的提示是什么。如果再次调用,该函数不仅必须能够替换“%”之间的内容,还必须能够替换同一字符串中包含的 #1 或 #2。
    【解决方案3】:

    /%.+?%/ 应该可以解决问题。
    查看正则表达式的贪婪性。
    [^%] 在第一个 % 处停止。但是您想包含两个%s 之间的所有字符。

    【讨论】:

    • .+?,你是说.*吗?
    • 不,这行不通。考虑X%A%B%C%Y — 他想从ABC 中提取三个匹配项,而您的模式不会这样做,因为您只会以这种方式找到AC
    • .+?.* 之间存在差异。 .* 是贪婪的,.+? 是懒惰的。当您还想匹配%%时,可以使用.*?
    • @tchrist 这个问题不清楚。我希望将%A% %B% 匹配到A,B。我不像你那样理解这个问题。
    • @MaPePeR 但无论如何,他的正则表达式应该可以工作。你的只是比较慢。我认为在他提交代码之前我们不会看到他的问题。
    【解决方案4】:

    试试这个表达方式

    %[a-zA-Z0-9# ]*%
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多