Coldfusion 正则表达式生成 slug

Posted

技术标签:

【中文标题】Coldfusion 正则表达式生成 slug【英文标题】:Coldfusion regex to generate slug 【发布时间】:2016-08-19 18:29:40 【问题描述】:

我有这个功能可以在 Coldfusion 中生成 slug:

<cffunction name="generateSlug" output="false" returnType="string">
    <cfargument name="str">
    <cfargument name="spacer" default="-">

    <cfset var ret = "" />

    <cfset str = lCase(trim(str)) />
    <cfset str = reReplace(str, "[àáâãäå]", "a", "all") />
    <cfset str = reReplace(str, "[èéêë]", "e", "all") />
    <cfset str = reReplace(str, "[ìíîï]", "i", "all") />
    <cfset str = reReplace(str, "[òóôö]", "o", "all") />
    <cfset str = reReplace(str, "[ùúûü]", "u", "all") />
    <cfset str = reReplace(str, "[ñ]", "n", "all") />
    <cfset str = reReplace(str, "[^a-z0-9-]", "#spacer#", "all") />
    <cfset ret = reReplace(str, "#spacer#+", "#spacer#", "all") />

    <cfif left(ret, 1) eq "#spacer#">
        <cfset ret = right(ret, len(ret)-1) />
    </cfif>
    <cfif right(ret, 1) eq "#spacer#">
        <cfset ret = left(ret, len(ret)-1) />
    </cfif>

    <cfreturn ret />
</cffunction>

然后我用这个来称呼它:

<cfset stringToBeSlugged = "This is a string abcde àáâãäå èéêë ìíîï òóôö ùúûü ñ año ñññññññññññññ" />
<cfset slug = generateSlug(stringToBeSlugged) />
<cfoutput>#slug#</cfoutput>

但这是输出我这个蛞蝓:

this-is-a-string-abcde-a-a-a-a-a-a-e-e-e-e-i-i-i-o-o-o-o-u-u-u-u-n-a-no-n-n-n-n-n-n-n-n-n-n-n-n-n

似乎所有重音字符都已正确替换,但此函数在替换它们后插入了一个“-”。为什么?

哪里出错了?

PD:我期待这个输出

this-is-a-string-abcde-aaaaaa-eeee-iiii-oooo-uuuu-n-ano-nnnnnnnnnnnnn 

谢谢。

【问题讨论】:

您期望上述函数的输出是什么? 然后删除&lt;cfif left(ret, 1) eq "#spacer#"&gt; &lt;cfset ret = right(ret, len(ret)-1) /&gt; &lt;/cfif&gt; &lt;cfif right(ret, 1) eq "#spacer#"&gt; &lt;cfset ret = left(ret, len(ret)-1) /&gt; &lt;/cfif&gt;部分 我在 python 中模仿了你的例子,如果你期望的输出是正确的,我认为不需要那部分 @rock321987 抱歉,但它不起作用。相同的输出,与预期不同:-( 在 cf10,11 和 2016 上正常工作。在 trycf.com 上测试。 trycf.com/gist/4f861b82a8c700e2d9dbefb896abb56e/… 【参考方案1】:

这对你有用吗? (我已经改编了我们内部使用的类似脚本。)我相信我们在 ColdFusion 8 中使用了它,因为我们仍在使用它和 CF9。

<cffunction name="generateSlug" output="false" returnType="string">
    <cfargument name="str" default="">
    <cfargument name="spacer" default="-">
    <cfset var ret = replace(arguments.str,"'", "", "all")>
    <cfset ret = trim(ReReplaceNoCase(ret, "<[^>]*>", "", "ALL"))>
    <cfset ret = ReplaceList(ret, "À,Á,Â,Ã,Ä,Å,Æ,È,É,Ê,Ë,Ì,Í,Î,Ï,Ð,Ñ,Ò,Ó,Ô,Õ,Ö,Ø,Ù,Ú,Û,Ü,Ý,à,á,â,ã,ä,å,æ,è,é,ê,ë,ì,í,î,ï,ñ,ò,ó,ô,õ,ö,ø,ù,ú,û,ü,ý,&nbsp;,&amp;", "A,A,A,A,A,A,AE,E,E,E,E,I,I,I,I,D,N,O,O,O,O,O,0,U,U,U,U,Y,a,a,a,a,a,a,ae,e,e,e,e,i,i,i,i,n,o,o,o,o,o,0,u,u,u,u,y, , ")>
    <cfset ret = trim(rereplace(ret, "[[:punct:]]"," ","all"))>
    <cfset ret = rereplace(ret, "[[:space:]]+","!","all")>
    <cfset ret = ReReplace(ret, "[^a-zA-Z0-9!]", "", "ALL")>
    <cfset ret = trim(rereplace(ret, "!+", arguments.Spacer, "all"))>
    <cfreturn ret>
</cffunction>

<cfset stringToBeSlugged = "This is a string abcde àáâãäå èéêë ìíîï òóôö ùúûü ñ año ñññññññññññññ" />
<cfoutput>"#stringToBeSlugged# = #generateSlug(stringToBeSlugged)#</cfoutput>

支持更多国际字符

如果您想扩大对国际字符的支持,您可以使用 ICU4J (java) 和 Paul Hastings 的 Transliterator.CFC 来音译所有字符,然后用破折号替换任何剩余的空格、破折号、斜杠等。

https://gist.github.com/JamoCA/ec4617b066fc4bb601f620bc93bacb57

http://site.icu-project.org/download

两者都安装好后,可以通过识别语言id(要转换成的)和传递要转换的字符串来转换非拉丁字符:

<cfset Transliterator = CreateObject("component","transliterator")>

<cfoutput>
<cfloop array="#TestStrings#" index="TestString">
<h3>TestString = "#TestString#"</h3>
<blockquote>
    <div>CFC-1 = #Transliterator.transliterate('Latin-ASCII', TestString)#</div>
    <div>CFC-2 = #Transliterator.transliterate('any-NFD; [:nonspacing mark:] any-remove; any-NFC', TestString)#</div>       
</blockquote>
<hr>
</cfloop>
</cfoutput>

<h2>Available Language IDs</h2>
<cfdump var="#Transliterator.getAvailableIDs()#" label="Language IDs">

【讨论】:

以上是关于Coldfusion 正则表达式生成 slug的主要内容,如果未能解决你的问题,请参考以下文章

PHP 正则表达式匹配Slug

Rails4:模型验证 slug 列的“格式”正则表达式

路由中uri slug的codeigniter正则表达式

正则表达式 slug 在另一个词之前

Django中的Slug Url正则表达式

Django Urls - 具有相同正则表达式的两个视图