【问题标题】:Using pattern matching to sort from a file, Java使用模式匹配从文件中排序,Java
【发布时间】:2019-01-29 01:03:13
【问题描述】:

所以我已经让我的程序能够正确分隔文本文件的行,甚至可以匹配第一行文本的模式,但我还需要能够检测和分隔地址行文本文件并根据它们的方向或街道/百老汇对它们进行排序,但我什至无法为地址设置检测到初始模式。我使用正则表达式是否错误,这就是地址部分无法正确检测到的原因吗?

代码

package csi311;

// Import some standard Java libraries.
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.ArrayList;
/**
 * Hello world example.  Shows passing in command line arguments, in this case a filename. 
 * If the filename is given, read in the file and echo it to stdout.
 */
public class HelloCsi311 {

    /**
     * Class construtor.
     */
    public HelloCsi311() {
    }


    /**
     * @param filename the name of a file to read in 
     * @throws Exception on anything bad happening 
     */
    public void run(String filename) throws Exception {
        if (filename != null) {
            readFile(filename); 
        }
    }


    /**
     * @param filename the name of a file to read in 
     * @throws Exception on anything bad happening 
     */
    private void readFile(String filename) throws Exception {
        System.out.println("Dumping file " + filename); 
        // Open the file and connect it to a buffered reader.
        BufferedReader br = new BufferedReader(new FileReader(filename));  
        ArrayList<String> foundaddr = new ArrayList<String>();
        String line = null;  
        String pattern = "^\\d\\d\\d-[A-Za-z][A-Za-z][A-Za-z]-\\d\\d\\d\\d";
        String address[] = new String[4];
        address[0] = "\\d{1,3}\\s\\[A-Za-z]{1,20}";
        address[1] = "\\d{1,3}\\s\\[A-Za-z]{1,20}\\s\\d{1,3}\\[A-Za-z]{1,20}\\s\\[A-Za-z]{1,20}";
        address[2] = "\\d{1,3}\\s\\d{1,3}\\[A-Za-z]{1,20}\\s\\[A-Za-z]{1,20}";
        address[3] = "\\d\\d\\s\\[A-Za-z]{1,20}";
        Pattern r = Pattern.compile(pattern);
        // Get lines from the file one at a time until there are no more.
        while ((line = br.readLine()) != null) {
            if(line.trim().isEmpty()) {
                continue;
            }
            String sample = line.replaceAll("\\s+,", ",").replaceAll(",+\\s",",");
            String[] result = sample.split(",");
            String pkgId = result[0].trim().toUpperCase();
            String pkgAddr = result[1].trim();


            Float f = Float.valueOf(result[2]);
            for(String str : result){
                // Trying to match for different types
                for(String pat : address){
                    if(str.matches(pat)){
                        System.out.println(pat);
                    }
                }



                if(f < 50 && !pkgId.matches(pattern)) {
                    Matcher m = r.matcher(str);
                    if(m.find()) {
                        foundaddr.add(str);
                    }
                }
            }
        }

        if(foundaddr != null) {
            System.out.println(foundaddr.size());
        }   

        // Close the buffer and the underlying file.
        br.close();
    }



    /**
     * @param args filename
     */
    public static void main(String[] args) {
        // Make an instance of the class.
        HelloCsi311 theApp = new HelloCsi311();
        String filename = null; 
        // If a command line argument was given, use it as the filename.
        if (args.length > 0) {
            filename = args[0]; 
        }
        try { 
            // Run the run(), passing in the filename, null if not specified.
            theApp.run(filename);
        }
        catch (Exception e) {
            // If anything bad happens, report it.
            System.out.println("Something bad happened!");
            e.printStackTrace();
        }    
    }
}

文本文件

123-ABC-4567, 15 W. 15th St., 50.1
456-BGT-9876,22 Broadway,24
QAZ-456-QWER, 100 East 20th Street,50
Q2Z-457-QWER, 200 East 20th Street, 49
6785-FGH-9845 ,45 5th Ave, 12.2,
678-FGH-9846 ,45 5th Ave, 12.2

123-ABC-9999, 46 Foo Bar, 220.0
347-poy-3465, 101 B'way,24

下面是应该能够处理地址行的代码行,但由于某种原因,它与模式和正确分隔地址行的输出不匹配,并且可以在 for 循环上方的打印语句中看到处理地址,但由于某种原因,地址行甚至没有被检测为匹配项,我不知道为什么会这样。

代码行问题与

  for(String str : result){
      //System.out.println(str);
      // Trying to match for different types
      for(String pat : address){
          if(str.matches(pat)){
              System.out.println(pat);
          }
      }

所需输出 - 按要求编辑 -

22 Broadway
45 5th Ave
101 B'way

【问题讨论】:

  • 为什么不用逗号分割或使用适当的 CSV 解析器?您可能在这里不需要正则表达式。
  • 这些行以逗号分隔并单独打印就可以了,但是我需要能够匹配拆分行的模式,然后将它们分成我可以在 arraylist 中执行的特定部分但是问题是由于某种原因,地址部分的模式没有被检测到,我很困惑为什么这是我读过的关于正则表达式的所有内容,并且格式表明我的格式是正确的。这对于检测文件中文本第一部分的匹配模式效果很好。这和使用正则表达式是必需的。
  • 例如,456-BGT-9876 22 Broadway 24 678-FGH-9846 45 5th Ave 12.2 347-poy-3465 101 B'way 24 是打印出来的,我需要能够与22 Broadway 部分进行模式匹配。使用正则表达式,我什至专门针对该示例,但由于某种原因,即使那样它也没有被检测为匹配项。我需要能够检测到这个匹配,因为我需要对其进行调整,以便能够检测到 Broadway 部分,然后将其添加到 arraylist 作为传递到 Broadway 所需的传递
  • 你能把你想要的输出添加到问题中吗?我不完全明白你在找什么。
  • 完成,这就是我试图从文本文件中获取的输出,它在第一个逗号之后的任何内容,这就是交付的地址部分,我需要对这些地址进行模式匹配并能够打印他们出去。一旦我知道地址匹配错误然后担心匹配broadwayAveB'way的特定模式,在这种情况下Broadway and B'way都被认为是百老汇,将被归为一类数组列表分组。

标签: java regex sorting pattern-matching filereader


【解决方案1】:

我认为问题出在您的正则表达式上。例如\\d\\d\\s\\[A-Za-z]{1,20},在所有转义后变成\d\d\s\[A-Za-z]{1,20}。分解如下:

  • \d:匹配任意数字
  • \d:匹配任意数字
  • \s: 匹配任意空白字符
  • \[:匹配[ 字符
  • A-Za-z:匹配文字文本A-Za-z
  • ]:匹配文字字符]
    • {1,20}:匹配前面的字符 (]) 1-20 次。

您可能想要的正则表达式是\d\d\s[A-Za-z]{1,20},作为转义字符串是\\d\\d\\s[A-Za-z]{1,20}。请注意,[ 之前没有 \

要记住的其他一点是,正则表达式可以匹配字符串中的任何位置。例如,正则表达式a 将匹配字符串a,但也将匹配abcbacabracadabra 等。为避免这种情况,您必须使用锚定符号^$ 来分别匹配开始和结束。然后你的正则表达式变成^\\d\\d\\s[A-Za-z]{1,20}$

我还注意到,您正在使用 for 循环 for(String str : result){ 将每一列与正则表达式进行匹配。在我看来,您应该只匹配 result[1]pkgAddr

最后一点,看看Regex 101。它将允许您针对一堆输入测试您的正则表达式,以查看它们是否匹配。

【讨论】:

  • 非常感谢!修复了我的正则表达式问题,我对它的工作原理有了更好的了解,我的程序中仍有一些小问题,但没有什么是我无法解决的。
猜你喜欢
  • 2023-04-02
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 2022-01-16
  • 2021-10-07
相关资源
最近更新 更多