davies has asked for the wisdom of the Perl Monks concerning the following question:
The basic task I wish to accomplish is relatively simple. I want to execute a database command line UPDATE bugs_fulltext SET comments = $newtext WHERE comments = $oldtext. My instinctive approach was to use placeholders. The problem I am hitting is that the new and old text may contain line breaks. I can't use an index on the table as the table is part of BugZilla and the definition has no index, hence the WHERE comments = $oldtext clause (I have other clauses to deal with duplicate comments, but that's not relevant to my problem). Unfortunately, the database may deliver line breaks as 0D or 0D0A but insists that they be entered as \n so that it can enter them in the local format. The problem is that Perl, of course, has its own setting for \n that need not be the same. Indeed, Perl's \n and the database's \n are different "\n"s. So what I need to do is to replace either 0D or 0D0A with \n.
Doing this in a simple regex seems to work. Unfortunately, the text could legitimately contain xkcd://Bobby Tables, so I still need to pass it through the placeholder. This converts my \n to \\n, which means that the WHERE clause does not match. Bind does the same thing. I then tried using split on the string to get an array of individual lines, intending to pass each line separately through db->quote and join them with \ns. Unfortunately, the regex that worked for s///g did not work in split (the exact regex was chr(13)chr(10)?). However, db->quote, getting a single line, converted the 0D0A sequences to \r\n, which might give me some leverage. If I pass the text through db->quote and then s/\\r\\n/\\n/g, I think I will get what I want. Unless, of course, the character before the R is an escaped backslash, i.e. the character group is \\r\n, when I don't want to substitute. Unless THAT is preceded by ANOTHER backslash, when I DO want to substitute. Unless (repeat ad infinitum).So, I have two questions. Is there a better approach, given that I don't know what the localisation of Perl(\n) and database(\n) will be? Is there a way of writing s/\\r\\n/\\n/g unless preceded by an even number of backslashes, excluding the one given?
Regards,
John Davies
|
|---|