简体   繁体   English

用于Perl中文件操作的正则表达式不起作用

[英]regex for file operation in perl not working

I have a xml file contain data's like: 我有一个包含数据的xml文件,例如:

 <get>9090</get><br>
 <setId>setIdHere</set>
 <mainId>121</mainId>

As I'm not using any external lib/packages, however I'm need to do some changes using I/O. 由于我没有使用任何外部lib / packages,但是我需要使用I / O进行一些更改。

I need to change the string setIdHere with something . 我需要使用something更改字符串setIdHere Please find the perl code below: 请在下面找到perl代码:

my $filename="file1.xml";
my $idVal=3232;
open(my $fh , '>>' ,$fileName);
select $fh or die $!;
s/setIdHere/$idVal;
print;
select STDOUT;
close($fh);

The above code is appending the value in the end, but I want to replace it with the string setIdHere . 上面的代码在末尾附加值,但是我想用字符串setIdHere替换它。

I'm new to perl not sure what's wrong with the above code. 我是Perl的新手,不确定上面的代码有什么问题。

Thanks in advance. 提前致谢。

First off, your code is using some unusually outdated techniques. 首先,您的代码使用了一些异常过时的技术。 select $fh has a global effect and is best avoided. select $fh具有全局影响,最好避免使用。

In general to edit a file you need to open it for reading, read it in, alter it, and write it back out again. 通常,要编辑文件,您需要将其打开以进行读取,读入,更改和重新写回。 To avoid pulling the whole file into memory, the file can be very big, you generally do this line by line. 为了避免将整个文件拉入内存,文件可能会很大,通常逐行执行此操作。

You can't write to the same file you're reading from (well, you can, but it makes a mess), so instead you write to a temp file and then when you're done rename to be the original. 您不能写与您正在读取的文件相同(虽然可以,但是很混乱),所以您要写一个临时文件,然后在完成后重命名为原始文件。

# This forces you to declare all variables protecting against typos
use strict;
# This lets you know when you've done something you probably shouldn't.
use warnings;
# This will error if file operations failed, no more "or die $!"
use autodie;

my $file = "file1.xml";
my $tmp  = $file.".new";  # file1.xml.new

open my $in,  "<", $file;  # open the XML file for reading
open my $out, ">", $tmp;   # open a temp file for writing

# Read the file line by line
while(my $line = <$in>) {
    # Change the line.
    $line =~ s{this}{that}g;

    # Write it to the temp file.
    print $out $line;
}

# If you don't do this, it might not have finished writing.
close $out;
close $in;

# Overwrite the old file with the new one.
rename $temp, $file;

HOWEVER you're editing XML. 但是,您正在编辑XML。 XML is structured and you should not try to read and edit it with regexes. XML是结构化的,您不应尝试使用正则表达式读取和编辑它。 You instead need to parse it with an XML library like XML::LibXML or XML::Twig . 相反,您需要使用XML库(如XML :: LibXMLXML :: Twig)对其进行解析。

You say you can't use any external library, but I bet you can, it's just a matter of figuring out how. 您说不能使用任何外部库,但是我敢打赌,这只是弄清楚如何做的问题。 You'll have a much easier time of it if you do. 如果这样做的话,您会轻松得多。 Generally the reason is that you don't have admin privileges. 通常,原因是您没有管理员权限。 The simplest solution is to install perlbrew and install your own copy of Perl that you can manage. 最简单的解决方案是安装perlbrew并安装可以管理的自己的Perl副本。 Perlbrew makes this easy. Perlbrew使这变得容易。

Please, never ever use regular expressions to parse XM L. XML is contextual, and regular expressions are not. 不要使用正则表达式来解析XML。XML是上下文的,而正则表达式则不是。 Therefore it's only ever going to be a dirty hack. 因此,它永远只能将是一个肮脏的黑客。

I would recommend XML::Twig if you need to modify an XML file. 如果需要修改XML文件,我建议使用XML::Twig It supports xpath , which is like regular expressions, but inherently handles the context problem. 它支持xpath就像正则表达式一样,但是固有地处理了上下文问题。

XML::Twig also does 'parsefile_inplace' for in place editing of your file: XML::Twig还对文件进行就地编辑“ parsefile_inplace”:

#!/usr/bin/env perl

use strict;
use warnings;

use XML::Twig;

sub modify_setId {
    my ( $twig, $setId ) = @_;
    $setId -> set_text('3232');
    $twig -> flush; 
}

my $twig = XML::Twig -> new ( twig_handlers => { 'setId' => \&modify_setId } );
$twig -> set_pretty_print('indented'); 
$twig -> parsefile_inplace('test.xml');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM