2

I'm making cover letters for mailing of books and magazines. I have all data of recipients in the data base and I have PHP script fetching that data and making cover letters. A user who writes that cover letter using special characters to mark where the name should be put etc.

For example, in order to compose a cover letter an user writes:

Dear [[last_name]],

please find attached book...

Then it gets parsed by PHP script and [[last_name]] tag gets replaced with a real name. When 1000 addresses selected for mailing then the script produces 1000 cover letters each one with defferent name.

Now, in my Russian language word "Dear" has different ending for male and female. It is like we say on English "Dear mr." or "Dear mrs."

In order to mark that in the cover letter user writes the possible endings for the word:

Dear[[oy/aya]] [[last_name]]

or it could be something like:

Dear[[ie/oe]]... etc.

I'm trying to figure out the regular expression and replacement command for my PHP script to parse those kind of lines.

For the last_name tags I use:

$text = ...//this is text of the cover letter with all the tags.
$res = $mysqli->query("SELECT * FROM `addresses` WHERE `flag` = 1")
while ($row=$res->fetch_assoc()) {
    $text = str_replace('[[last_name]]', $row['lname'], $text);
    echo $text;
}

For the word endings as I understand it should be something like:

$text = preg_replace('/\w{2-3}\//\w{2-3}/', ($row['gender']==1) 
  ? 'regexp(first_half)' 
  : 'regext(second_half)', $text);

I could make this whole idea by cycling through the tag, parsing it and replace but it would be 5-10 lines of code. I'm sure this can be done just by the line above but I can't figure out how.

m59
  • 43,214
  • 14
  • 119
  • 136
user164863
  • 580
  • 1
  • 12
  • 29
  • I love to see people making their own solutions to problems that have already been solved (I really mean that) because it shows an interest in learning and trying to make things better. That being said, however, have you considered just grabbing a word processor like word (shudder) or Open Office Write and using Mail Merge? – Zarathuztra Dec 15 '13 at 17:30
  • It is a whole production line: one typing the cover letters, one selecting the addresses, one priting to cover letters and then few years later someone will want to see what was mailed and to whom, what was exactly the cover letter and were there any answers. If I just make the xls file and download it to the user who will make the cover letter then this cover letter will not gets stored in the data base with the very last corrections etc. – user164863 Dec 15 '13 at 17:37
  • maybe could be helpful http://stackoverflow.com/questions/20582312/regex-extract-string-between-2-curly-braces/20582631#20582631 – ilpaijin Dec 15 '13 at 17:38
  • You can just search for Dear (name), if gender of (name) [where i think you know it from MySQL) is male replace `Dear` with `Dearoy` otherwise `Dearaya`. So the user can simple write `Dear name` and the application just replace `Dear` with the correct word. – Marco Acierno Dec 15 '13 at 17:39
  • @user164863 You don't have to use excel, you can very easily use ODBC to connect your mail merge configs to a database, and get clever from there on. – Zarathuztra Dec 15 '13 at 17:39
  • I'm afraid that allowing external connections to the database will put it at risk. – user164863 Dec 15 '13 at 17:41
  • @Marco Lopez Acierno - I have thought about it but there are many different words could be used instead of Dear, such as "Hello", "Your Honour" etc. – user164863 Dec 15 '13 at 17:43

2 Answers2

2
$gender = ($row['gender'] == 1) ? 1 : 2;
preg_replace_callback('#\[\[(?:([^\]/]+)(?:/([^\]/]+))?\]\]#',
    function($match) use ($row, $gender) {
        // $match will contain the current match info
        // $match[1] will contain a field name, or the first part of a he/she pair
        // $match[2] will be non-empty only in cases of he/she etc
        return (empty($match[2])) ? $row[$match[1]] : $match[$gender];
    }
);
cHao
  • 84,970
  • 20
  • 145
  • 172
2

see http://www.phpliveregex.com/p/2BC and then you replace with $1 for male and $2 for female ...

preg_replace('~\[\[(.+?)/(.+?)\]\]~', $row['gender']==1?'$1':'$2', $text);
jko
  • 2,068
  • 13
  • 25
  • 1$ and 2$? What are you talking about? –  Dec 15 '13 at 18:01
  • @HamZa It worked for me, is there any particular cases it won't work? It takes 2 or 3 letters, whatever is marked – user164863 Dec 15 '13 at 18:06
  • @user689 its the answer fee) – user164863 Dec 15 '13 at 18:08
  • @HamZa: This actually would work...or, at least, something like it would, if you've already replaced [[field_names]]. If `$row['sex'] == 'male'`, then it's basically calling `preg_replace('....', "$1"...)`; otherwise, `preg_replace('...', "$2"...)`. Those strings (and the regex!) should probably be single-quoted, though, since you want the stuff within them to be interpreted by the PCRE engine rather than by PHP. – cHao Dec 15 '13 at 18:10
  • @cHao I just realised that he meant to use the ternary operator. But `=` != `==` – HamZa Dec 15 '13 at 18:42
  • fixed the code. sry, wrote it in a rash. was not tested. works also if [[field_names]] was not replaced already. I personally prefer `preg_replace_callback()` bit it is more advanced - so be sure to understand it before using it ;-) – jko Dec 15 '13 at 19:59