Re: String replace, another question
by moritz (Cardinal) on Aug 26, 2011 at 11:45 UTC
|
See How (Not) To Ask A Question. Your question is very unclear. For example what do you mean "run it from within the file"? What's in $line?
If $line indeed contains just a single line as the variable name suggests, the regex will never match, because it requires multiple lines in the same string.
| [reply] [d/l] [select] |
Re: String replace, another question
by kcott (Archbishop) on Aug 26, 2011 at 12:13 UTC
|
As indicated by moritz, this is a little too vague to provide a definitive answer. The following may help.
Perl Best Practices would recommend:
$line =~ s/.../.../gmsx;
Also, take a look at perlre.
| [reply] [d/l] |
Re: String replace, another question
by TomDLux (Vicar) on Aug 26, 2011 at 14:53 UTC
|
I don't understand the question, I'm blinded by the long lines and can' find the problems.
You can use just about any characters as delimiters in s///, you don't have to use the slash. By using something else, say matching curly braxes, you don't have to excape all those slashes that are part of the text. And you don't have to searcxh character by character to find the separation between 'search' and 'replace'.
As well, if you want to specify 5 spaces, you can use \s{5} rather than \s\s\s\s\s. It means you don't have to count; you KNOW the pattern is looking for 5 of them. Ooops, there's actually 6 of them....proves my point. It doesn't matter that braces are nested, cause braces are balanced.
# Up in the Constants section
#
Readonly my $NL = "\n";
Readonly my $RETURN = "\r";
Readonly my $SPACE = q{ };
Readonly my $TAB = "\t"
my $search_text = qr{<binddn>cn=abcde</binddn> # buttondown
$NL # newline
$SPACE{6} # 6 spaces
<bindpass> # something
.* # anything
</bindpass> # end something
}xms;
my $replace_text = "<binddn>cn=abcde</binddn>$RETURN$TAB<bindpass>welc
+ome1</bindpass>";
$line =~ s{$search_text} {$replace_text};
As Occam said: Entia non sunt multiplicanda praeter necessitatem.
| [reply] [d/l] [select] |
Re: String replace, another question
by graff (Chancellor) on Aug 27, 2011 at 01:10 UTC
|
I'm wondering if the OP text got updated after the first few replies were posted... Updating your post is okay, but you really should preserve the original content (e.g. put <strike>...</strike> around stuff to mark it as deleted), and point out what parts have been newly added. It helps to keep the discussion coherent.
As to the problem (as stated in the OP when I read it just now), this is not that different from the last thread you started -- did you happen to try the suggestions given there? (If yes, why not show what you tried? If not, why didn't you even try?)
I'd suggest something like this, IF you are confident that the xml input data is consistent enough to do it this way, without an xml parser (that is, the tags always show up on separate, consecutive lines, as shown in the OP) -- this applies one of the suggestions given by moritz in your previous thread:
my $change_next;
while (<>) {
if ( /<binddn>cn=xyzzz</ ) {
$change_next = 1;
}
elsif ( $change_next and /<bindpass>welcome1</ ) {
s/1/123/;
$change_next = undef;
}
print;
}
That'll work as a simple stdin-stdout filter:
perl name_of_script < old_file.xml > new_file.xml
| [reply] [d/l] [select] |
Re: String Manipulation
by ikegami (Patriarch) on Aug 26, 2011 at 19:50 UTC
|
local $/ = "";
while (<>) {
if (m{<binddn>cn=\Q$user\E</binddn>}) {
s{<bindpass>\K.*?(?=</bindpass>)}{$new_passwd};
}
print;
}
| [reply] [d/l] |
|
|
That regex does not preserve the <bindpass> tags and will replace the password in any case, not only when it is "welcome1".
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
| [reply] [d/l] |
|
|
Fixed the first. The second was intentional. (It's not clear whether he wants "to change the password that is 'welcome1' in the example" or if he wants "to change the password if it is 'welcome1'. I think the former is more likely, but you subscribe to the latter interpretation.)
| [reply] |
|
|
Re: String Manipulation
by CountZero (Bishop) on Aug 26, 2011 at 20:31 UTC
|
use Modern::Perl;
{local $/="\n\n";
while (<DATA>) {
s{<bindpass>welcome1</bindpass>}{<bindpass>welcome123</bindpass
+>} if m{^<binddn>cn=xyzzz</binddn>};
print;
}
}
__DATA__
<binddn>cn=abcde</binddn>
<bindpass>welcome1</bindpass>
<binddn>cn=abcde</binddn>
<bindpass>welcome1</bindpass>
<binddn>cn=xyzzz</binddn>
<bindpass>welcome1</bindpass>
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James
| [reply] [d/l] |
Re: String Manipulation
by moritz (Cardinal) on Aug 26, 2011 at 19:53 UTC
|
You can use the same approaches as presented in the replies to Search and replace query. Why do you ask nearly the same question all over again?
| [reply] |