正则表达式删除范围内除 D 之外的每个字符之后的数字

问题描述 投票:0回答:3

我想删除范围内除 D 之外的所有类型字符之后的数字,..>.

正则表达式

(?:^<F=(?=.+>)|\G(?!^)).*[^d]\K[0-9]+
  1. 这能够捕获不在d之后的数字。但是,它不会一次捕获所有这些数字。它从后面捕获。当我们删除最后捕获的数字时,它从左到右匹配下一个。

    rt7

    8
    d7

    rt

    7
    d7

    9D6kl>rtd7

  2. 数字先出现在 = 未被捕获之后。 1H9D6kl>rt78d7

更新 2:将

[^d]
更改为
(?<!d)
解决此问题

  1. 匹配过程应该在=和>之间,..>。但是在
    >
    之后输入的数字也被捕获了。 rt7
    8
    d7

更新 3:更改 (?=.

+
>) 到 (?=.
*
>) 并将位置更改为 end (?:^(?=.*>) 解决这个问题。 它只捕获
>

之前的数字

预期输出:

<F=HD6kl>rt78d7

对于所有可能的情况:
输入:rt78d7
搭配:1H

2
D6
3
k
43
l
5
>rt78d7
输出:rt78d7

php regex regex-lookarounds
3个回答
0
投票

有了向前看和向后看,一个简单的字符串函数就可以满足您的要求。 POC:

<?php
$string = '<F=1H2D63k43l5>rt78d7';
echo "Original: $string\n";
echo "Expected: <F=HD6kl>rt78d7\n";


function formatString($string){
    $end = $extension = strrchr( $string, '>'); // rt78d7

    $chars = str_split($string);
    $count = 0;
    $new_string = ''; 
    foreach ($chars as $key=>$item) {
        $prev = $count-1;
        if( $item == '>' ){
            break;
        }
        if( is_numeric($item) && substr($string, $prev, 1) != 'D' ){
            // do nothing
        } else {
            $new_string .= $item;
        }
        $count++;
    }
    return $new_string.$end;
}

$new = formatString($string);
echo "Actual:   ".$new."\n";

?>

结果:

原文:rt78d7

预期:rt78d7

实际:rt78d7


0
投票

ok,我们可以将正则表达式分成两部分,稍后加入。

  • 第 1 部分 -

    ((?<!D)\d+
    。我们使用否定后向匹配仅匹配前面没有
    D
    的数字。

  • 第 2 部分 -

    (?=.*?>)
    。我们只匹配
    =
    >
    之间的数字。假设你的字符串模板化得很好,如果我们只使用正则表达式正前瞻来寻找
    >
    就足够了。

将它们连接起来后的最终正则表达式是

((?<!D)\d+)(?=.*?>)
.

这意味着只匹配那些前面没有

D
并且后面没有
>
的数字。

片段:

<?php

$str = '<F=1H2D63k43l5>rt78d7';
$str = preg_replace('/((?<!D)\d+)(?=.*?>)/i','', $str);
var_dump($str === '<F=HD6kl>rt78d7');

在线演示


0
投票

您可以选择匹配

D
后跟数字:

(?:^<F=|\G(?!^)(?=[^\n>]*>))(?:D\d)?[^\d>\n]*\K\d+

说明

  • (?:
    备选方案的非捕获组
    • ^<F=
      断言字符串的开头然后匹配
      <F=
    • |
    • \G(?!^)
      在上一场比赛的末尾断言当前位置,而不是在字符串的开头
    • (?=[^\n>]*>)
      正面前瞻,声明除
      >
      (或换行符)以外的可选字符,然后匹配
      >
  • )
    关闭非捕获组
  • (?:D\d)?
    可选择匹配一个
    D
    字符后跟一个数字(或使用
    \d+
    表示 1 个以上的数字)
  • [^\d>\n]*
    匹配数字以外的可选字符
    >
    或换行符(如果您不想匹配交叉线)
  • \K
    忘记到目前为止匹配的是什么
  • \d+
    匹配1个以上的数字

查看 regex 演示PHP 演示

$re = '/(?:^<F=|\G(?!^)(?=[^\n>]*>))(?:D\d)?[^\d>\n]*\K\d+/mi';
$s = '<F=1H2D63k43l5>rt78d7';

echo preg_replace($re, "", $s);

输出

<F=HD6kl>rt78d7
© www.soinside.com 2019 - 2024. All rights reserved.