完美的亚马逊链接正则表达式

6

我正在尝试构建用于JavaScript的完美Amazon链接正则表达式。目前为止,这是我的代码:

var reg = /https?:\/\/(www|smile)\.amazon\.com\/(?:(?:[\w-]+\/)?(?:dp|gp\/product)\/(\w{10})\/)?/;

我希望这能完全匹配以下所有网址:

http://smile.amazon.com/dp/B0005ZH4QI/?tag=menasheh02-20&psc=1&smid=ATVPDKIKX0DER
http://www.amazon.com/gp/family/signup/info/?ie=UTF8&camp=1789&creative=9325&linkCode=ur2&ref_type=generic&refcust=5FNWKEJKP63HFBSY6JGLXL4XIQ&tag=menasheh02-20&linkId=HR76ZTGJKWO5ED2N
http://www.amazon.com/gp/redirect.html?ie=UTF8&location=https%3A%2F%2Fwww.amazon.com%2Fgp%2Fsubscribe-and-save%2Fmanager%2Fviewsubscriptions%3Fie%3DUTF8%26ref_%3Dya%255FT15%255F33&tag=menasheh02-20&linkCode=ur2&camp=1789&creative=390957
http://www.amazon.com/gp/student/signup/info?ie=UTF8&refcust=7EATHY4IXOFTTEMLIHVC3YL6DI&ref_type=generic
http://www.amazon.com/gp/video/primesignup?tag=menasheh02-20
https://smile.amazon.com/dp/B0005ZH4QI/?tag=menasheh02-20&psc=1&smid=ATVPDKIKX0DER
https://smile.amazon.com/s/ref=s9_acss_gb_cg_HTLLPCGB_3d1?fst=as%3Aoff&rh=n%3A165793011%2Cn%3A!2334111011%2Cn%3A!2334173011%2Cn%3A15539865011%2Cp_n_age_range%3A165936011%2Cp_72%3A1248963011&bbn=15539865011&ie=UTF8&qid=1476851901&rnid=1248961011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=events-center-c-4&pf_rd_r=8MKN8SY6C5ZP4NC1C0RB&pf_rd_t=701&pf_rd_p=e4acec8d-70de-466a-be44-05291b40a5d4&pf_rd_i=HTL_desktop
https://www.amazon.com/b/ref=s9_acss_gb_cg_HTLLPCGB_11a1?node=13521759011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=events-center-c-4&pf_rd_r=8MKN8SY6C5ZP4NC1C0RB&pf_rd_t=701&pf_rd_p=e4acec8d-70de-466a-be44-05291b40a5d4&pf_rd_i=HTL_desktop
https://www.amazon.com/Doctor-Vortex-Manipulator-Sonic-Screwdriver/dp/B001PR1ZII/ref=gbph_tit_e-7_fb02_fc8a0d34?smid=AOUT97QIB451U&pf_rd_p=8e268714-ad3d-444b-b0df-d51d8825fb02&pf_rd_s=events-center-c-7&pf_rd_t=701&pf_rd_i=HTL_desktop&pf_rd_m=ATVPDKIKX0DER&pf_rd_r=8MKN8SY6C5ZP4NC1C0RB
https://www.amazon.com/dp/B0005ZH4QI/?tag=menasheh02-20&psc=1&smid=ATVPDKIKX0DER
https://www.amazon.com/gp/coupon/skippy-baking-sale/A2UI00T2I5JAV3?ie=UTF8&heroAsin=B0005ZH4QI&source=grid_db_13285418011&pf_rd_p=782d30de-8b22-4b3d-9009-0f7a0cb995d3&pf_rd_s=merchandised-search-3&pf_rd_t=Landing&pf_rd_i=13285418011&pf_rd_m=ATVPDKIKX0DER&pf_rd_r=PPNJHXVZRMM4XP9KXGGG
https://www.amazon.com/Monster-High-School-Playset/dp/B006O6F932/ref=gbph_tit_e-7_fb02_85d3d028?smid=A3CXJV2JYTL237&pf_rd_p=8e268714-ad3d-444b-b0df-d51d8825fb02&pf_rd_s=events-center-c-7&pf_rd_t=701&pf_rd_i=HTL_desktop&pf_rd_m=ATVPDKIKX0DER&pf_rd_r=8MKN8SY6C5ZP4NC1C0RB
https://www.amazon.com/s/ref=s9_acss_gb_cg_HTLLPCGB_3d1?fst=as%3Aoff&rh=n%3A165793011%2Cn%3A!2334111011%2Cn%3A!2334173011%2Cn%3A15539865011%2Cp_n_age_range%3A165936011%2Cp_72%3A1248963011&bbn=15539865011&ie=UTF8&qid=1476851901&rnid=1248961011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=events-center-c-4&pf_rd_r=8MKN8SY6C5ZP4NC1C0RB&pf_rd_t=701&pf_rd_p=e4acec8d-70de-466a-be44-05291b40a5d4&pf_rd_i=HTL_desktop

而且这些都不包括:

https://www.google.com/search?safe=active&site=&source=hp&q=bad+regex&oq=bad+regex&gs_l=hp.3..0j0i22i30k1l9.724.2089.0.2265.10.9.0.0.0.0.269.1091.0j4j2.6.0....0...1c.1.64.hp..4.5.821.0..0i20k1j0i131k1j0i10k1.k62wRudUpsw
https://sellercentral.amazon.com/B53C945A8D?randomstuff=34341&otherrandomstuff=2

现在,它既不匹配坏的网址之一,这部分相对简单。(它也不匹配含有gp/redirect.html?的url。)棘手的部分是让匹配返回每个有用部分的url,特别是考虑到if/else和#。

# 工作中 #

match[1] 应该等于 "www" 或 "smile." 中的一个。

match[2] 应该等于 ASIN,如果url没有 /dp/%ASIN%%SEO-string%/dp/%ASIN% 或者 /gp/product/%ASIN%,则为空白。

# 不工作 #

match[3] 应该等于 .com 后面的剩余url,或者在设置了ASIN的情况下,应该等于产品后面的剩余url,但不包括结尾的#。

match[4] 应该等于从 match[3] 开始到 tag=,如果存在的话。

match[5] 应该等于 tag 参数,如果存在的话。

match[6] 应该等于标签参数(如果存在,则为空)和 # 之间的 url 的其余部分,如果没有 # 则为结束位置

match[7] 应该等于结尾处的 # 和任何后面的内容,如果没有则为空

我刚开始接触更复杂的正则表达式,遇到了一些问题,例如如果有 #,就不能一直到行末等等。

有更有经验的人可以帮忙吗?谢谢。


使用正则表达式字面量,而不是 RegExp 构造函数。 - Tushar
@Tushar 用于match函数?你是什么意思? - Menasheh
1
var regex = /https?:\/\/(www|smile)\.amazon\.com\/(?:(?:[\w-]+\/)?(?:dp|gp\/product)\/(\w{10})\/)?([\w\/=-]+)?([\w\/?=-]+)?(\?.+)(#[\w]+)?/; 然后 # Not Working In JS # 问题将得到解决。在 RegExp 构造函数中,需要将字符串作为参数传递并转义斜杠。 - Tushar
1
值得一提的是,使用URL API来细分URL并独立处理组件可能是值得考虑的。如果您没有锚标签,请创建一个带有URL的锚标签(甚至不需要将其放入DOM),然后您可以访问anchor.hostnameanchor.pathnameanchor.search等,这样您就不必尝试在单个难以阅读的正则表达式中完成所有工作。 - ShadowRanger
@MayorMonty,您是在建议迁移吗? - Menasheh
显示剩余5条评论
1个回答

5

尝试使用以下适用于JavaScript的正则表达式:

https?:\/\/(?=(?:....)?amazon|smile)(www|smile)\S+com(((?:\/(?:dp|gp)\/([A-Z0-9]+))?\S*[?&]?(?:tag=))?\S*?)(?:#)?(\w*?-\w{2})?(\S*)(#?\S*)+

我做了一点改动:

match[3] & match[4] = match[2] & match[3]

match[2] = match[4].

希望对你有所帮助。
演示地址:https://regex101.com/r/sT2wj8/2

为什么谷歌和销售会涉及其中 - 他们不应该匹配!这是专门针对亚马逊网址的。 - Menasheh
1
@Menasheh 他们不是。这个符号 ?! 位于它们之前,意思是“不匹配括号内的内容”。无论如何,我已经更新了代码并将它们删除了。请在演示中查看匹配的组。 - Ibrahim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接