簡體   English   中英

匹配“ {$”且不匹配“ \\ {$”的正則表達式

[英]Regular expression that matches “{$” AND NOT matches “\{$”

我正在一個使用詞法分析的項目中,基本上我必須生成是文本的標記而不是文本的標記。

  • "{$"序列之前,作為文本的令牌被視為所有字符。
  • 不是文本的標記被視為"{$""$}"序列內的所有字符。

請注意,可以通過編寫"\\{$"轉義 "{$"字符序列,因此這也成為text的一部分。
我的工作是讀取文本 字符串 ,為此,我正在使用正則表達式

我正在使用Java ScannerPattern類,這是到目前為止的工作:

String text = "This is \\{$ just text$}\nThis is {$not_text$}."
Scanner sc = new Scanner(text);
Pattern textPattern = Pattern.compile("{\\$"); // insert working regex here
sc.useDelimiter(textPattern);

System.out.println(sc.next());

這是應該打印出來的內容:

這是\\ {$ just text $}
這是

如何為以下邏輯語句創建正則表達式

匹配 “ {$” ,不匹配 “ \\ {$”

您可以在\\{\\$前面使用負向后看 (?<!\\\\) ,以確保轉義的花括號不匹配:

(?<!\\)\{\$

演示版

可能的解決方案:

String text = "This is \\{$ just text$}\nThis is {$not_text$}.";
Pattern textPattern = Pattern.compile(
          "(?<text>(?:\\\\.|(?!\\{\\$).)+)" // text - `\x` or non-start-of `{$`
        + "|"                        // OR
        + "(?<nonText>\\{\\$.*?\\$\\})");      // non-text
Matcher m = textPattern.matcher(text);
while (m.find()) {
    if (m.group(1)!=null){
        System.out.println("text : "+m.group("text"));
    }else{
        System.out.println("non-text : "+m.group("nonText"));
    }
}
System.out.println("\01234");

說明:

從我看來,您希望\\成為用於轉義的特殊字符
現在的問題是確定\\后面的字符/序列的轉義位置,以及何時應將其視為簡單的可打印字符(文字)。

(可能的問題)
假設您有文本dir1\\dir2\\並且要在其后添加非文本foo 你會怎么寫?

您可以嘗試編寫dir1\\dir2\\{$foo$}但這可能意味着您剛剛轉義了{$ ,這將防止foo被視為非文本。

在Java中,String文字面臨相同的問題,因為\\可以用於使用以下命令創建其他特殊字符

  • \\n \\r \\t \\"
  • Unicode代碼點\￿
  • 八進制格式\\012

Java(和許多其他語言)中使用的解決方案使\\總是特殊的字符才能創建\\文字,而該字符必須用另一個\\進行轉義(實際上並不需要為此添加另一個特殊字符)。 因此,要表示\\我們需要將其編寫為\\\\

因此,如果我們有dir1\\dir2\\文本,則需要將其寫為dir1\\\\dir2\\\\ 這將使我們可以將其連接到{$non-text$}而不必擔心在{$之前放置的最后一個\\\\會引起對它的誤解,並防止將其視為非文本序列。

因此,現在當我們看到dir1\\\\dir2\\\\{$foo$}我們可以正確解釋{$

從這一點出發,我假設您也使用這種方法來確保對\\正確解釋。

現在,讓我們嘗試創建規則,該規則將使我們可以查找/分隔文本和非文本字符。

根據我們的示例,我們知道dir1\\\\dir2\\\\{$foo$}是:文本dir1\\\\dir2\\\\和非文本{$foo$}
因此,如您所見,在{$后面沒有\\拆分有時會失敗(如果前面\\數目不是奇數)。

可能更簡單的解決方案是接受

  • 對於文本:
    • \\\\. -表示以\\開頭的字符的正則表達式(這將處理\\\\文字並轉義\\{ (這還將允許我們接受$..$}部分的其余部分)
    • (?!\\{\\$). -表示不是{字符的正則表達式,它將以{$區域開頭。
  • 對於非文本:
    • \\{\\$.*?\\$\\} -表示{$...$}正則表達式-我們知道它將被轉義,因為所有轉義的字符都將被\\\\.接受\\\\.

暫無
暫無

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

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