亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

相對于什么是在 java.util.Scanner 中評估的正則表達式?

相對于什么是在 java.util.Scanner 中評估的正則表達式?

慕容708150 2023-03-09 10:18:04
我注意到以下我無法解釋的奇怪行為:import java.util.Scanner;public class Main {  public static void main(String[] args) {    var scanner = new Scanner("ab");    System.out.println(scanner.findInLine("."));  // output: a    System.out.println(scanner.findInLine("."));  // output: b  }}但import java.util.Scanner;public class Main {  public static void main(String[] args) {    var scanner = new Scanner("ab");    System.out.println(scanner.findInLine("."));  // output: a    System.out.println(scanner.findInLine("^.")); // output: null  }}我不明白第二個片段與第一個片段有何不同。根據文檔,^匹配一行的開頭,但事實并非如此,因為:a在行匹配的開頭,a在輸入匹配的開頭,以及b在掃描儀匹配的位置。如果正則表達式不是相對于掃描儀的位置進行評估的,那么它相對于什么進行評估?
查看完整描述

2 回答

?
守候你守候我

TA貢獻1802條經驗 獲得超10個贊

關于這兩個代碼片段,掃描器只是通過了a而不是整行。要轉到下一行,您需要調用scanner.nextLine().

類的 findInLine(Pattern pattern) 方法java.util.Scanner嘗試查找指定模式的下一次出現,忽略定界符。如果在下一個行分隔符之前找到模式,則 掃描器前進到匹配的輸入并返回與模式匹配的字符串。如果在直到下一個行分隔符的輸入中沒有檢測到這樣的模式,則返回 null 并且掃描儀的位置不變。

https://www.geeksforgeeks.org/scanner-findinline-method-in-java-with-examples/

例子:

    Scanner scanner = new Scanner("abcde\nx");
    System.out.println(scanner.findInLine("."));    // output: a
    System.out.println(scanner.findInLine("."));    // output: b

這里掃描器匹配了第一個字符 (a) 并移動到仍在同一行的 b。

    Scanner scanner = new Scanner("abcde\nx");
    System.out.println(scanner.findInLine("."));     // output: a
    scanner.nextLine();
    System.out.println(scanner.findInLine("."));     // output: x

在這里,掃描儀的工作方式與以前相同,但我已經移過了第一行分隔符。


查看完整回答
反對 回復 2023-03-09
?
Smart貓小萌

TA貢獻1911條經驗 獲得超7個贊

一切都在那里,只是記錄不完整。以下是findInLine實現方式:


public String findInLine(Pattern pattern) {

    // omitted: validate parameters

    // omitted: ensure the internal buffer is large enough


    return findWithinHorizon(pattern, horizonForLine);

}

來源:java/util/Scanner.java


以下是文檔必須說明的內容findWithinHorizon:


[...] 掃描儀將地平線視為透明的、非錨定的邊界 [...]。


來源:java.util.Scanner#findWithinHorizon(java.util.regex.Pattern,int)


關于錨定邊界:


[...] 如果沒有錨定邊界,這個匹配器區域的邊界將不會匹配諸如^和 之類的錨點$。[...]


來源:java.util.regex.Matcher##useAnchoringBounds(boolean)


以下是findWithinHorizon實現方式:


public String findWithinHorizon(Pattern pattern, int horizon) {

    // omitted: validate parameters


    while (true) {

        if (findPatternInBuffer(pattern, horizon)) {

            matchValid = true;

            return matcher.group();

        }


        // omitted: check if more input is required

    }

    return null;

}

來源:java/util/Scanner.java


以下是findPatternInBuffer實現方式:


private boolean findPatternInBuffer(Pattern pattern, int horizon) {

    // omitted: calculating search limit


    matcher.region(position, searchLimit);


    // omitted: matching pattern

}

java/util/Scanner.java


這就是為什么第二個模式不匹配的原因。正則表達式只在光標前搜索,不認為^適用于光標所在位置。但是它適用于輸入的開頭,因此第一個模式匹配。


這并不意味著每個帶有的正則表達式^都會失敗,后面的正面觀察會起作用:


import java.util.Scanner;


public class Main {

  public static void main(String[] args) {

    var scanner = new Scanner("ab");


    System.out.println(scanner.findInLine("."));        // output: a

    System.out.println(scanner.findInLine("(?<=^.).")); // output: b

  }

}


查看完整回答
反對 回復 2023-03-09
  • 2 回答
  • 0 關注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號