VB.net 的正则表达式

发布于 2024-10-05 16:29:15 字数 438 浏览 6 评论 0原文

我有一个txt文件,其内容

$NETS  
P3V3_AUX_LGATE;  PQ6.8 PU37.2   
U335_PIN1;  R3328.1 U335.1  
$END  

需要以此格式更新,并保存回另一个txt文件

$NETS  
'P3V3_AUX_LGATE';  PQ6.8 PU37.2  
'U335_PIN1';  R3328.1 U335.1  
$END

注意:行数可能高达10,000行

我当前的解决方案是读取txt文件行按行检测“;”是否存在和换行符并进行更改。

现在我有一个保存所有行的变量,是否有其他方法(例如通过正则表达式替换)来进行更改而无需循环遍历每一行,这样我可以轻松打印结果

并跟进问题,哪个更有效?

I have a txt file with content

$NETS  
P3V3_AUX_LGATE;  PQ6.8 PU37.2   
U335_PIN1;  R3328.1 U335.1  
$END  

need to be updated in this format, and save back to another txt file

$NETS  
'P3V3_AUX_LGATE';  PQ6.8 PU37.2  
'U335_PIN1';  R3328.1 U335.1  
$END

NOTE: number of lines may go up to 10,000 lines

My current solution is to read the txt file line by line, detect the presence of the ";" and newline character and do the changes.

Right now i have a variable that holds ALL the lines, is there other way something like Replace via RegEx to do the changes without looping thru each line, this way i can readily print the result

and follow up question, which one is more efficient?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

歌枕肩 2024-10-12 16:29:15

尝试

ResultString = Regex.Replace(SubjectString, "^([^;\r\n]+);", "'$1';", RegexOptions.Multiline)

使用多行字符串。

这将在行的开头找到任何字符串(长度为一个或多个),直到第一个分号(如果有),并将其替换为其带引号的等效项。

它应该比您现在所做的逐行循环字符串更有效,但如果您有疑问,则必须对其进行分析。

Try

ResultString = Regex.Replace(SubjectString, "^([^;\r\n]+);", "'$1';", RegexOptions.Multiline)

on your multiline string.

This will find any string (length one or more) at the start of a line up until the first semicolon if there is one and replace it with its quoted equivalent.

It should be more efficient than looping through the string line by line as you're doing now, but if you're in doubt, you'd have to profile it.

不疑不惑不回忆 2024-10-12 16:29:15

您可能可以使用 \w+; 之类的内容找到所有匹配项,但我不知道如何使用 Regex.Replace 添加 ' 但保留原始匹配项。

但是,如果您已经将其作为一个变量,则不必再次读取该文件,您可以让代码查找所有 ;,然后查找每个变量的前一个换行符,或者您可以可以在换行符上使用 String.Split 来分割你已经进入行的变量。
如果你想将其返回到一个变量,你可以使用 String.Join< /a>.

就我个人而言,我通常会使用 String.Split (如果需要,可能会使用 String.Join)方法,因为我认为这将使代码易于阅读。

You could probably find all the matches using something like \w+; but I don't know how you'd be able to do a replace on that using Regex.Replace to add the 's but keep the original match.

However, if you already have it as one variable, you don't have to read the file again, either you could make your code find all ;s and then find the previous newline for each, or you could use a String.Split on newlines to split the variable you've already got into lines.
And if you want to get it back to one variable you can just use String.Join.

Personally I'd normally use the String.Split (and possibly the String.Join if needed) method, since I think that would make the code easy to read.

ぇ气 2024-10-12 16:29:15

我会说是的!这可以通过正则表达式来完成。确保您打开了“多行”选项,并使用一些捕获组来制作正则表达式以简化工作。

然而我可以说这不是最佳的。既然您提到了可以处理的行数,那么使用流式方法而不是内存中方法似乎更“资源明智”。

采用正则表达式方法(这花了 15 分钟,所以请不要认为这是最佳解决方案,只需证明它可行)

    private static Regex matcher = new Regex(@"^\$NETS\r\n(?<entrytitle>.[^;]*);\s*(?<entryrest>.*)\r\n(?<entrytitle2>.[^;]*);\s*(?<entryrest2>.*)\r\n\$END\r\n", RegexOptions.Compiled | RegexOptions.Multiline);
    static void Main(string[] args)
    {
        string newString = matcher.Replace(ExampleFileContent, new MatchEvaluator(evaluator));
    }

    static string evaluator(Match m)
    {
        return String.Format("$NETS\r\n'{0}'; {1}\r\n'{2}'; {3}\r\n$END\r\n",
                              m.Groups["entrytitle"].Value,
                              m.Groups["entryrest"].Value,
                              m.Groups["entrytitle2"].Value,
                              m.Groups["entryrest2"].Value);            
    }

希望这有帮助,

I would say Yes! this can be done with Regular expressions. Make sure you got the "multiline" option turned on and craft your regular expression using some capture groups to ease the work.

I can however say this will NOT be the optimal one. Since you mention the amount of lines you could be processing, it seems 'resource wise' smarter to use a streaming approach instead of the in memory approach.

Taking the Regex approach (and this took 15 mins so please don't think this is an optimal solution, just prove it would work)

    private static Regex matcher = new Regex(@"^\$NETS\r\n(?<entrytitle>.[^;]*);\s*(?<entryrest>.*)\r\n(?<entrytitle2>.[^;]*);\s*(?<entryrest2>.*)\r\n\$END\r\n", RegexOptions.Compiled | RegexOptions.Multiline);
    static void Main(string[] args)
    {
        string newString = matcher.Replace(ExampleFileContent, new MatchEvaluator(evaluator));
    }

    static string evaluator(Match m)
    {
        return String.Format("$NETS\r\n'{0}'; {1}\r\n'{2}'; {3}\r\n$END\r\n",
                              m.Groups["entrytitle"].Value,
                              m.Groups["entryrest"].Value,
                              m.Groups["entrytitle2"].Value,
                              m.Groups["entryrest2"].Value);            
    }

Hope this helps,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文