什么是C#Regex相当于Java的appendReplacement和appendTail

时间:2022-09-01 09:47:08

UPDATE

Here is what I came up with. I haven't tested it yet because it is part of a much larger piece of code that still needs to be ported.

这就是我想出的。我还没有测试它,因为它是仍然需要移植的更大代码片段的一部分。

Can you see anything that looks out of place?

你能看到任何看起来不合适的东西吗?

private const string tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%";
string html = "some html";
int p = 0;
var userBlock = new ArrayList();

MatchCollection matcher = preservePatterns[p].Matches(html);
int index = 0;
StringBuilder sb = new StringBuilder();
int lastValue = 0;

foreach(Match match in matcher){
    string matchValue = match.Groups[0].Value;

    if(matchValue.Trim().Length > 0) {
        userBlock.Add(matchValue);

        int curIndex = lastValue + match.Index;
        sb.Append(html.Substring(lastValue, curIndex));
        sb.AppendFormat(tempUserBlock, p, index++);

        lastValue = curIndex + match.Length;
    }
}

sb.Append(html.Substring(lastValue));
html = sb.ToString();

ORIGINAL POST BELOW:

以下原始帖子:

Here is the original Java:

这是原始的Java:

private static final String tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%";
String html = "some html";
int p = 0;
List<String> userBlock = new ArrayList<String>();

Matcher matcher = patternToMatch.matcher(html);
int index = 0;
StringBuffer sb = new StringBuffer();
while (matcher.find())
{
    if (matcher.group(0).trim().length() > 0)
    {
        userBlock.add(matcher.group(0));
        matcher.appendReplacement(sb, MessageFormat.format(tempUserBlock, p, index++));
    }
}
matcher.appendTail(sb);
html = sb.toString();

And my C# conversion so far

到目前为止我的C#转换

private const string tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%";
string html = "some html";
int p = 0;
var userBlock = new ArrayList();

MatchCollection matcher = preservePattern.Matches(html);
int index = 0;
StringBuilder sb = new StringBuilder();

for(var i = 0; i < matcher.Count; ++i){
    string match = matcher[i].Groups[0].Value;
    if(match.Trim().Length > 0) {
        userBlock.Add(match);
        // WHAT DO I DO HERE?
        sb.Append( string.Format(tempUserBlock, p, index++) );            
    }
}
// WHAT DO I DO HERE?
matcher.appendTail(sb);
html = sb.toString();

See comment above, where I ask, "WHAT DO I DO HERE?"

请参阅上面的评论,在那里我问,“我在这做什么?”

Clarification
The Java code above is performing string replacement on some HTML. It saves the originally replaced text because it needs to be re-inserted later after some whitespace compression is completed.

澄清上面的Java代码是在某些HTML上执行字符串替换。它保存了原来替换的文本,因为在完成一些空格压缩后需要重新插入。

2 个解决方案

#1


5  

There's no need to reproduce Java's appendReplacement/appendTail functionality; .NET has something better: MatchEvaluator. Check it out:

没有必要重现Java的appendReplacement / appendTail功能; .NET有更好的东西:MatchEvaluator。一探究竟:

string holder = "Element {0} = {1}";
string s0 = "111 222 XYZ";
ArrayList arr = new ArrayList();

string s1 = Regex.Replace(s0, @"\d+",
  m => string.Format(holder, arr.Add(m.Value), m.Value)
);

Console.WriteLine(s1);
foreach (string s in arr)
{
  Console.WriteLine(s);
}

output:

Element 0 = 111 Element 1 = 222 XYZ
111
222

There are several ways to implement the MatchEvaluator, all thoroughly discussed in this article. This one (lambda expressions) is by far the coolest.

有几种方法可以实现MatchEvaluator,这些都在本文中进行了详细讨论。这个(lambda表达式)是迄今为止最酷的。

#2


2  

I'm not familiar with the Java regex classes, but this is my C# interpretation of what I think your code does:

我不熟悉Java正则表达式类,但这是我对你的代码所做的C#解释:

private const string tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%"; 
string html = "some html"; 
int p = 0; 
var userBlock = new List<string>(); 

MatchCollection matcher = preservePattern.Matches(html); 
StringBuilder sb = new StringBuilder(); 
int last = 0;
foreach (Match m in matcher)
{
    string match = m.Groups[0].Value; 
    if(match.Trim().Length > 0) { 
        userBlock.Add(match); 
        sb.Append(html.Substring(last, m.Index - last));
        sb.Append(m.Result(string.Format(tempUserBlock, p, index++)));
    }
    last = m.Index + m.Length;
}
sb.Append(html.Substring(last));
html = sb.ToString(); 

#1


5  

There's no need to reproduce Java's appendReplacement/appendTail functionality; .NET has something better: MatchEvaluator. Check it out:

没有必要重现Java的appendReplacement / appendTail功能; .NET有更好的东西:MatchEvaluator。一探究竟:

string holder = "Element {0} = {1}";
string s0 = "111 222 XYZ";
ArrayList arr = new ArrayList();

string s1 = Regex.Replace(s0, @"\d+",
  m => string.Format(holder, arr.Add(m.Value), m.Value)
);

Console.WriteLine(s1);
foreach (string s in arr)
{
  Console.WriteLine(s);
}

output:

Element 0 = 111 Element 1 = 222 XYZ
111
222

There are several ways to implement the MatchEvaluator, all thoroughly discussed in this article. This one (lambda expressions) is by far the coolest.

有几种方法可以实现MatchEvaluator,这些都在本文中进行了详细讨论。这个(lambda表达式)是迄今为止最酷的。

#2


2  

I'm not familiar with the Java regex classes, but this is my C# interpretation of what I think your code does:

我不熟悉Java正则表达式类,但这是我对你的代码所做的C#解释:

private const string tempUserBlock = "%%%COMPRESS~USER{0}~{1}%%%"; 
string html = "some html"; 
int p = 0; 
var userBlock = new List<string>(); 

MatchCollection matcher = preservePattern.Matches(html); 
StringBuilder sb = new StringBuilder(); 
int last = 0;
foreach (Match m in matcher)
{
    string match = m.Groups[0].Value; 
    if(match.Trim().Length > 0) { 
        userBlock.Add(match); 
        sb.Append(html.Substring(last, m.Index - last));
        sb.Append(m.Result(string.Format(tempUserBlock, p, index++)));
    }
    last = m.Index + m.Length;
}
sb.Append(html.Substring(last));
html = sb.ToString();