Forum Moderators: phranque

Message Too Old, No Replies

Rewrite with repeated strings

         

toumimi

11:15 am on Dec 29, 2010 (gmt 0)

10+ Year Member



Hi all,

I know quite well Apache rewriting, but now, I need your help for a special RewriteRule...

Url to match (simplified) :
mysite.com/TYPE-LOC/rents-TYPE-LOC/TYPE-NBROOM-LOC.html

LOC is a locality name and is repeated three times.
TYPE is a property type (house,appartment,parking,...) and is repeated three times too.
NBROOM is another string to match.

I need to match this url (if possible in one rule with RewriteConds).
Easy.
But I need to make sure first LOC is the same as second LOC, as would be TYPE param.

Of course I can catch all and send it to a php script to check but it would be better to achieve it in my .htaccess

Here is my rewrite rule that I want to have :
RewriteRule ^([^-]+)-([^/]+)/rents-[^-]+-[^/]+/[^-]+-([0-9])-.*\.html page.php?type=$1&loc=$2&nbroom=$3 [QSA,L]


And if I could be more specific for type of property I want to match, it would be perfect, but I don't want to repeat the complete list, if you know what I mean :)

RewriteRule ^(house|appartment|parking)-([^/]+)/rents-[^-]+-[^/]+/[^-]+-([0-9])-.*\.html page.php?type=$1&loc=$2&nbroom=$3 [QSA,L]


So, question is :
How would you do this kind of urls, which seems to be impossible in Apache Rewrite system ?

I tried something like that, but $1 and $2 are only available in test string (not pattern).
RewriteCond %{REQUEST_URI} ^/$1-$2/rents-$1-$2/$1
RewriteRule ^(house|appartment|parking)-([^/]+)/rents-[^-]+-[^/]+/[^-]+-([0-9])-.*\.html page.php?type=$1&loc=$2&nbroom=$3 [QSA,L]


I also tried something like that, but %1 and %2 are only available in test string (not pattern).
RewriteCond %{REQUEST_URI} ^/(house|appartment|parking)-([^/]+)/
RewriteRule ^%1-%2/rents-%1-%2/%1-([0-9])-%2\.html page.php?type=%1&loc=%2&nbroom=$1 [QSA,L]


Thanks in advance :D
Florian

g1smd

1:23 pm on Dec 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If you capture the first LOC in backreference %x and the second LOC in %y, you can use a RewriteCond to compare the two. Beware that you can have only a maximum of 9 backreferences in a condition or rule.

Or you could use a RewriteCond to compare "%1>$2" and "$1>%2" where ">" is an arbitary character that does not appear in any real URL.

toumimi

1:44 pm on Dec 29, 2010 (gmt 0)

10+ Year Member



Hey,

Thanks for your answer !

I tried something like that but it's not working.
RewriteCond %{REQUEST_URI} ^/(house|appartment|parking)-([^/]+)/ # Catch type and locname
RewriteCond $1_$4_$6 ^%1_%1_%1$ # Check property types
RewriteCond $2_$5_$8 ^%2_%2_%2$ # Check locality names
RewriteRule ^([^-]+)-([^/]+)/(rent)-([^-]+)-([^/]+)/([^-]+)-([0-9])-(.+)\.html [...]


I'll check in RewriteLog for more informations...

Any idea about that solution ?


Florian

g1smd

2:10 pm on Dec 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Actually I am thinking you don't need %n at all, you could compare just $n, with two conditions for each part. One checks $1_$2 = $2_$1 and the other checks $1_$3 = $3_$1.

I haven't tested these ideas, as I'm actually in the middle of some complicated PHP code and took a break from that for a few minutes.

toumimi

2:47 pm on Dec 29, 2010 (gmt 0)

10+ Year Member



I'm afraid this is not possible to use back-references in pattern string.
Neither % or $ are interpreted and Apache is trying to match invalid strings :
input='appartment_appartment' pattern='^$4_$1$' => not-matched

So I don't understand how you want to do a check like this: $1 = $3.


Problem still here...

g1smd

3:01 pm on Dec 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'll have to look back at how jdMorgan has done types of these comparisons in the past. The exact syntax evades me right now.

toumimi

10:52 am on Dec 30, 2010 (gmt 0)

10+ Year Member



Hey !

Has anybody an answer for my small problem ?

toumimi

9:06 am on Jan 3, 2011 (gmt 0)

10+ Year Member



I don't think it's possible.

I will be forced to use php to check each string equality.

Please tell me if someone knows how to achieve that...


Thanks,
Florian

jdMorgan

6:59 pm on Jan 5, 2011 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There is no variable-to-variable compare in mod_rewrite.

However, on servers which support PCRE regular-expressions, you can use an "atomic back-reference" within the regular-expressions pattern-matching engine to do this.

The technique is based on commutativity -- that is, if A+B is equal to A+A, then A=B. This applies to both numerical and lexical compares.

Here is a simple example you can apply to your task:

# Rewrite if "A" and "B" are equal in the URL-path /<a>/<b>
RewriteCond $1<>$2 ^(.*)<>\1$
RewriteRule ^([^/]+)/(.+)$ <some-target-path> [L]

"\1$" is the atomic back-reference and is not at all the same thing as $1.

And note again that this technique requires that your server support PERL-Compatible Regular Expressions. Most Apache 2.0 and later servers do, while most Apache 1.x servers do not.

Jim

toumimi

10:53 am on Jan 6, 2011 (gmt 0)

10+ Year Member



Thanks you very much !

I knew that we could do this back-reference in php but never seen that in any .htaccess example.

In fact, I didn't test this back-reference in a RewriteCond and that was the key !

An easier solution for your code is using REQUEST_URI and then match immediately what I want.
So RewriteRule don't need to be complicated, and everything takes place in RewriteCond.

Here is what I am using and it's working very well :)
RewriteCond %{REQUEST_URI} ^/(house|appartment|parking)-([^/]+)/rents-\1-\2/\1-([0-9])-.*\.html$
RewriteRule .? page.php?type=%1&loc=%2&nbroom=%3 [QSA,L]



This post is what I was searching for :D
Thanks, Florian