【问题标题】:C# Regex Pattern Index for Multiple Patterns多个模式的 C# 正则表达式模式索引
【发布时间】:2016-06-16 17:51:18
【问题描述】:
// same pattern, but different look-aheads
// 'same' followed by 'X', 'Y', or 'Z'
string[] patterns = new string[]{
    "same(?=\\s*X)",
    "same(?=\\s*Y)",
    "same(?=\\s*Z)"
};

// replacements with respect to above patterns
string[] replacements = new string[]{
    "abc",
    "def",
    "ghi"
};

// now, I need to replace 'same' with a different
// string depending on the character after it
string input = "same X same Y same Z";
var regex = new Regex( string.Join("|", patterns) );
regex.Replace(input, m => replacements[m.PATTERN_INDEX]);

上面的代码中是否有内置的东西可以给我PATTERN_INDEX

注意:我不能使用哈希表查找,因为我根据前瞻用不同的替换字符串替换相同的模式。

【问题讨论】:

  • 您的意思是您需要将 pattern1 替换为 abc 并将 pattern2 替换为 def?见ideone.com/q9ayK8
  • stackoverflow.com/questions/628556/…这里可能对你有帮助。
  • 请把你的问题说清楚,更新一下
  • @WiktorStribiżew 差不多,除了我有两个以上的模式。这只是一个例子。
  • @bitwise:你的意思是你有一个带有交替组的正则表达式,你想知道哪个 branch 匹配?这不可能。您需要将每个分支包含在一个单独的捕获组中,然后检查哪个组匹配。

标签: c# regex


【解决方案1】:

在我的解决方案中,我在三个不同的捕获组(分别是第二个、第三个和第四个;第一个是捕获的空间)中捕获 X、Y 和 Z。

使用调用回调函数(名为 CallBack),我在每个组中查看哪一个具有值并替换为正确的文本(“abc”、“def”或“ghi”)。

这里的关键元素是回调函数。有时,要进行非常复杂的替换(例如您问题中的条件替换),您绝对需要使用回调函数。

这里的另一个关键概念是,如果捕获组无法匹配任何内容,则它们将返回一个空字符串。

using System;
using System.Text.RegularExpressions;

    string input = "same X same Y same Z";

    var myRegex = new Regex("same(\\s*)(?:(X)|(Y)|(Z))", RegexOptions.IgnoreCase);

    string output = myRegex.Replace(input, Callback);

    Console.WriteLine(output);

static string Callback(Match match) {

    string toReturn = "";

    if (match.Groups[2].Value != "") {

        toReturn = "abc";

    } else if (match.Groups[3].Value != "") {

        toReturn = "def";

    } else if (match.Groups[4].Value != "") {

        toReturn = "ghi";
    }

    return toReturn + match.Groups[1].Value + match.Groups[2].Value + 
        match.Groups[3].Value + match.Groups[4].Value;
}

你可以在这里测试它:http://csharppad.com/gist/5c921d27cefad32a6d353a26a6906405

我已经很多年没有接触过 C#了,我花了很长时间才写出那个简单的代码示例,所以不要指望我会提供太多进一步的帮助。

成功

编辑:我将用 PHP 编写算法,因为这是我现在使用最多的语言。

$test = new Test();

echo $test->callbackregex(
    '/same(\s*)(?:(X)|(Y)|(Z))/i',
    array(
        2 => array('abc', '$1' ,'$2'),
        3 => array('def', '$1' ,'$3'),
        4 => array('ghi', '$1' ,'$4')
    ),
    "same X same Y same Z"
);

class Test
{
    private $replacement = array();

    public function callbackregex($regex, array $replacement, $input)
    {
        $this->replacement = $replacement;

        return preg_replace_callback(
            $regex, 
            array($this, "callback"),
            $input
        );
    }

    private function callback($matches)
    {
        $toReturn = "";
        $total = count($matches);

        //I skip 0 because it is the overall match of the regex
        for($index = 1; $index < $total; $index++) {

            if (!empty($matches[$index]) and isset($this->replacement[$index])) {

                $replacementArray = $this->replacement[$index];

                if (is_string($replacementArray)) {

                    $replacementArray = array($replacementArray);
                }

                foreach ($replacementArray as $replacement) {

                    if (preg_match('/^\$\d+$/', $replacement)) {

                        $i = (int) str_replace('$', '', $replacement);

                        if (isset($matches[$i])) {

                            $toReturn .= $matches[$i];
                        }

                    } else {

                        $toReturn .= $replacement;
                    }

                }

            }
        }

        return $toReturn;
    }
}

测试:http://sandbox.onlinephpfunctions.com/code/85a5547c7194b36c763a0f8dc7672e5785ec2044

【讨论】:

  • 谢谢,虽然这可能会奏效,但它比仅使用 3 个单独的正则表达式搜索要复杂得多。
  • 最后,虽然在我自己搜索了一些之后,我不认为存在这样的内置功能,即使它绝对可行,甚至可以合理地期待它,当你可以通过几个模式时一次。
  • 如果你能找到一种方法使回调函数不是静态的(它们不是非 PHP),你可以将你的替换数组放在一个类变量中并在函数中访问它。不是静态替换,而是在匹配数组中循环查找哪个索引不为空,并将其与替换数组中完全相同的索引匹配(测试是否存在,否则用空字符串替换)。
  • 我使用 PHP 代码示例编辑了我的答案。这应该让您很好地了解如何实现您想要的。在这里测试:sandbox.onlinephpfunctions.com/code/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-08
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 2014-09-05
相关资源
最近更新 更多