簡體   English   中英

正則表達式:如何匹配任何字符串,直到空格,或直到標點后跟空格?

[英]Regex: how to match any string until whitespace, or until punctuation followed by whitespace?

我正在嘗試編寫一個正則表達式,它將在純文本字符串中找到URL,以便我可以用錨標記包裝它們。 我知道已有表達式可用於此 ,但我想創建自己的表達式 ,主要是因為我想知道它是如何工作的。

如果我的正則表達式失敗,它不會破壞任何東西,我的計划是寫一些相當簡單的東西。 到目前為止,這意味着:1)在單詞的開頭匹配“www”或“http”2)保持匹配直到單詞結束。

我能做到這一點,AFAICT。 我有這個: \\b(http|www).?[^\\s]+

哪個適用於foo www.example.com bar http://www.example.com等。

問題是,如果我給它foo www.example.com, http://www.example.com它認為逗號是URL的一部分。

因此,如果我要使用一個表達式來執行此操作,我需要更改“...當你看到空格時停止”到“......當你在空白之前看到空格或一個標點符號時停止”。 這是我不知道該怎么辦。

目前,我正在考慮運行的解決方案是添加另一個測試 - 匹配URL,然后在下一行移動任何偷偷摸摸的標點符號。 這不是那么優雅。

注意:我是用PHP編寫的。

旁白:為什么在上面的表達式中用\\b替換\\s似乎不起作用?


ETA:

感謝大家!

根據Explosion Pills的建議,這是我最終得到的結果:

function add_links( $string ) {
    function replace( $arr ) {
        if ( strncmp( "http", $arr[1], 4) == 0 ) {
            return "<a href=$arr[1]>$arr[1]</a>$arr[2]$arr[3]";
        } else {
            return "<a href=" . "http://" . $arr[1] . ">$arr[1]</a>$arr[2]$arr[3]";
        }
    }
return preg_replace_callback( '/\b((?:http|www).+?)((?!\/)[\p{P}]+)?(\s|$)/x', replace, $string );
}

我添加了一個回調,以便所有鏈接都以http://開頭,並且做了一些擺弄處理標點符號的方法。

它可能不是最好的做事方式,但它有效。 我在最后一段時間里學到了很多東西,但還有更多要學習的東西!

preg_replace('/
    \b       # Initial word boundary
    (        # Start capture
    (?:      # Non-capture group
    http|www # http or www (alternation)
    )        # end group
    .+?      # reluctant match for at least one character until...
    )        # End capture
    (        # Start capture
    [,.]+    # ...one or more of either a comma or period.
             # add more punctuation as needed
    )?       # End optional capture
    (\s|$) # Followed by either a space character or end of string
    /x', '<a href="\1">\1</a>\2\3'

......可能就是你想要的。 我認為它仍然不完美,但它至少應該滿足您的需求。

旁白:我認為這是因為\\b匹配標點符號

你可以通過積極的先行斷言來實現這一目標:

\b(http:|www\.)(?:[^\s,.!?]|[,.!?](?!\s))+

在Regexr上看到它。

手段,匹配任何東西,但空白,.!? 或者匹配,.!? 什么時候沒有空格。

旁白: 單詞邊界不是字符或一組字符,您不能將它放入字符類。 它是一個零寬度斷言,匹配從單詞字符到非單詞字符的變化。 在這里,我相信,字符類中的\\b被解釋為退格字符(字符串轉義序列)。

問題可能在於點,這意味着正則表達式中的“任何字符”。 你可能不得不逃避它:

\b(http|www)\.?[^\s]+

然后,問號意味着0或1,所以你說“可選點”不是你想要的(對吧?):

\b(http|www)\.[^\s]+

現在,它只會匹配http. www. 所以你需要告訴你接受的其他角色:

\b(http|www)\.[^\s\w]+

要么

\b(http|www)\.[^\sa-zA-Z]+

所以現在你說,

  • 在一個詞的邊界
  • 檢查httpwww
  • 放點
  • 允許任何范圍的azAZ ,不允許任何空白字符
  • 其中一個或多個

注意 - 我沒有測試過這些,但希望它們是正確的。


除此之外(我的看法) - \\s表示'空白'。 \\b表示'字邊界'。 []表示“允許的字符范圍”。 ^表示'不'。 +表示“一個或多個”。

所以當你說[^\\b]+你說'不允許這個字符范圍內的字邊界,並且必須有一個或多個'並且因為那里沒有別的東西>沒有別的東西被允許>沒有一個或更多>它可能會破裂。

你應該嘗試這樣的事情:

\b(http|www).?[\w\.\/]+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM