簡體   English   中英

在Java中使用正則表達式獲取n個單詞

[英]Get n Number of words using regex in Java

我有一本書的一部分,包括標點符號,換行符等,我希望能夠從文本中提取前n個單詞,並將其分為5部分。 正則表達式使我迷惑。 這就是我正在嘗試的。 我創建一個索引大小為0的數組,其中包含所有輸入文本:

public static String getNumberWords2(String s, int nWords){
    String[] m = s.split("([a-zA-Z_0-9]+\b.*?)", (nWords / 5));
    return "Part One: \n" + m[1] + "\n\n" + 
           "Part Two: \n" + m[2] + "\n\n" + 
           "Part Three: \n" + m[3] + "\n\n" +
           "Part Four: \n" + m[4] + "\n\n" + 
           "Part Five: \n" + m[5];
}

謝謝!

我認為最簡單,最有效的方法就是簡單地反復查找“單詞”:

Pattern p = Pattern.compile("(\\w+)");
Matcher m = p.matcher(chapter);
while (m.find()) {
  String word = m.group();
  ...
}

您可以通過修改正則表達式來更改“單詞”的定義。 我寫的只是使用正則表達式的單詞字符概念,我想知道它是否可能比您嘗試做的更合適。 但是,例如,它不會包含引號字符,您可能需要在單詞中允許使用引號字符。

使用BreakIterator為此有更好的選擇。 這將是解析Java中單詞的最正確方法。

(請參見下面的中斷部分,以便下一步進行。由於思想過程,將頂部留在這里...)

根據我對split() javadoc的閱讀,我想我知道發生了什么事。

您要基於空格分割字符串,最多n次。

String [] m = s.split("\\b", nWords);

然后,如果需要,將它們與令牌空格重新縫合在一起:

StringBuffer strBuf = new StringBuffer();
for (int i = 0; i < nWords; i++) {
    strBuf.append(m[i]).append(" ");
}

最后,將其切成五個相等的字符串:

String [] out = new String[5];
String str = strBuf.toString();
int length = str.length();
int chopLength = length / 5;
for (int i = 0; i < 5; i++) {
    int startIndex = i * chopLength;
    out[i] = str.substring(startIndex, startIndex + choplength); 
}

對我而言,這是深夜,所以您可能需要檢查一下自己是否正確。 我想我在正確的區號中找到了它。


好的,這里是第3個嘗試。通過調試器運行它之后,我可以驗證剩下的唯一問題是將不是5的因子切成五段的整數進行整數運算,以及如何最好地處理其余字符。

它不是很漂亮,但是可以。

String[] sliceAndDiceNTimes(String victim, int slices, int wordLimit) {
    // Add one to the wordLimit here, because the rest of the input string
    // (past the number of times split() does its magic) will be in the last
    // array member
    String [] words = victim.split("\\s", wordLimit + 1);
    StringBuffer partialVictim = new StringBuffer();

    for (int i = 0; i < wordLimit; i++) {
        partialVictim.append(words[i]).append(' ');
    }

    String [] resultingSlices = new String[slices];
    String recycledVictim = partialVictim.toString().trim();
    int length = recycledVictim.length();
    int chopLength = length / slices;

    for (int i = 0; i < slices; i++) {
        int chopStartIdx = i * chopLength;
        resultingSlices[i] = recycledVictim.substring(chopStartIdx, chopStartIdx + chopLength);
    }

    return resultingSlices;
}

重要筆記:

  • “ \\ s”是正確的正則表達式。 使用\\ b會導致很多額外的分割,因為單詞的開頭和結尾都有單詞邊界。
  • 在拆分運行次數上增加了一個,因為String數組中的最后一個數組成員是未拆分的剩余輸入字符串。 您也可以拆分整個字符串,並按原樣使用for循環。
  • 整數除法余數仍然是發問者的一項練習。 :-)

我只是猜測你在這里需要什么; 希望這是接近的:

public static void main(String[] args) {
    String text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " +
        "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
        "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris " +
        "nisi ut aliquip ex ea commodo consequat. Rosebud.";

    String[] words = text.split("\\s+");
    final int N = words.length;
    final int C = 5;
    final int R = (N + C - 1) / C;
    for (int r = 0; r < R; r++) {
        for (int x = r, i = 0; (i < C) && (x < N); i++, x += R) {
            System.out.format("%-15s", words[x]);
        }
        System.out.println();
    }
}

這將產生:

Lorem          sed            dolore         quis           ex             
ipsum          do             magna          nostrud        ea             
dolor          eiusmod        aliqua.        exercitation   commodo        
sit            tempor         Ut             ullamco        consequat.     
amet,          incididunt     enim           laboris        Rosebud.       
consectetur    ut             ad             nisi           
adipisicing    labore         minim          ut             
elit,          et             veniam,        aliquip        

另一種可能的解釋

這使用java.util.Scanner

static String nextNwords(int n) {
    return "(\\S+\\s*){N}".replace("N", String.valueOf(n));
}   
static String[] splitFive(String text, final int N) {
    Scanner sc = new Scanner(text);
    String[] parts = new String[5];
    for (int r = 0; r < 5; r++) {
        parts[r] = sc.findInLine(nextNwords(N / 5 + (r < (N % 5) ? 1 : 0)));
    }
    return parts;
}
public static void main(String[] args) {
    String text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " +
      "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " +
      "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris " +
      "nisi ut aliquip ex ea commodo consequat. Rosebud.";

    for (String part : splitFive(text, 23)) {
        System.out.println(part);
    }
}

這會打印text的前23個單詞,

Lorem ipsum dolor sit amet, 
consectetur adipisicing elit, sed do 
eiusmod tempor incididunt ut labore 
et dolore magna aliqua. Ut 
enim ad minim 

或者,如果7:

Lorem ipsum 
dolor sit 
amet, 
consectetur 
adipisicing 

或者,如果3:

Lorem 
ipsum 
dolor 
<blank>
<blank>

我有一個非常丑陋的解決方案:

public static Object[] getNumberWords(String s, int nWords, int offset){
    Object[] os = new Object[2];
    Pattern p = Pattern.compile("(\\w+)");
    Matcher m = p.matcher(s);
    m.region(offset, m.regionEnd());
    int wc = 0;
    String total = "";
    while (wc <= nWords && m.find()) {
      String word = m.group();
      total += word + " ";
      wc++;
    }
    os[0] = total;
    os[1] = total.lastIndexOf(" ") + offset;
    return os; }

    String foo(String s, int n){
    Object[] os = getNumberWords(s, n, 0);
    String a = (String) os[0];
    String m[] = new String[5];
    int indexCount = 0;
    int lastEndIndex = 0;
    for(int count = (n / 5); count <= n; count += (n/5)){
        if(a.length()<count){count = a.length();}
        os = getNumberWords(a, (n / 5), lastEndIndex);
        lastEndIndex = (Integer) os[1];
        m[indexCount] = (String) os[0];
        indexCount++;
    }
    return "Part One: \n" + m[0] + "\n\n" + 
    "Part Two: \n" + m[1] + "\n\n" + 
    "Part Three: \n" + m[2] + "\n\n" +
    "Part Four: \n" + m[3] + "\n\n" + 
    "Part Five: \n" + m[4];
}

暫無
暫無

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

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