1

I'm stuck trying to get the PHP preg_replace to work properly. I want to find all matches of a pattern and replace them with a string. But, for some reason, it's finding only partial matches and replacing all of them. I'm trying to remove the "password" from every line of a text file. The password is always at the end of each line, contains 4 to 8 alpha-numeric characters, and always follows two pipe characters.

Example:

$data = 'A00000001|A00000001|FirstName|LastName|email@address|Role||password'.PHP_EOL;
$data .= 'B00000002|B00000002|FirstName|LastName|email@address|Role||password'.PHP_EOL;
$delim = '|';

$newData = preg_replace("/".$delim.$delim."[a-zA-Z0-9]{4,8}/", $delim.$delim, $data);
echo $newData;

Output:

||||||1|||||||||1|||||||||e||||||||||||e||m||a||i||l||@||a||d||d||r||e||s||s|||||R||o||l||e|||||||||||| ||||||2|||||||||2|||||||||e||||||||||||e||m||a||i||l||@||a||d||d||r||e||s||s|||||R||o||l||e|||||||||||| ||

I've tried many variations with different groupings using parenthesis, putting back to back [a-zA-Z0-9] patterns instead of {#}. I've tried adding line start ^ and end $ to my pattern. I'm stuck. I know this will end up being something simple to that I'm just overlooking. That's why I need some fresh eyes on this.

Swede
  • 13
  • 2
  • Relevant info: http://stackoverflow.com/questions/1531456/is-there-a-php-function-that-can-escape-regex-patterns-before-they-are-applied – Tim Pietzcker Jun 26 '13 at 15:42

3 Answers3

3

You should use this regex

/(?<=\|\|)[a-zA-Z]{4,8}$/

You need to escape | since it represents OR in regex

$ marks the end of string

(?<=\|\|) is a zero width lookbehind

Anirudha
  • 32,393
  • 7
  • 68
  • 89
  • When I used your regex pattern, it only removed the "password" in the 2nd line. I'm assuming this is due to the lookbehind portion. You're correct about escaping the pipe. I knew it would be something simple. Thank you. – Swede Jun 26 '13 at 16:51
0

I'm trying to remove the "password" from every line of a text file.

In this case, anchor the regex after properly escaping your delimiter. Assuming the delim shouldn't be kept either, you could use:

preg_replace('/\|.*?$/', '', $data);

If it should, use a look-behind or:

preg_replace('/\|.*?$/', '|', $data);

On a separate note: this looks like an SQL dump or a CSV file. If so, consider using whichever variation of COPY ... DELIMITER ... your RDBMS offers instead:

http://www.postgresql.org/docs/current/static/sql-copy.html

You could then create a temporary table, import, drop the column, do whatever else you need to do, and populate the final tables as needed once you're done.

Denis de Bernardy
  • 75,850
  • 13
  • 131
  • 154
  • Thanks Denis. I fixed it by escaping the pipe char. This is manipulating a csv file that I don't have control over how it's being made. This is a temporary fix until it can be fixed properly on the other party's side. – Swede Jun 26 '13 at 16:53
0

Looks like you can just escape your delimiters.

$newData = preg_replace('/\'.$delim.'\'.$delim.'[a-zA-Z0-9]{4,8}/', $delim.$delim, $data);
Adam
  • 772
  • 3
  • 10
  • 1
    Perfect, thanks. Although, I had to use double escapes with my double-quoted code: `$newData = preg_replace("/\\".$delim."\\".$delim."[a-zA-Z0-9]{4,8}/", $delim.$delim, $data);` – Swede Jun 26 '13 at 16:54