【问题标题】:Using regex to get String between quotation marks from a txt file in Java使用正则表达式从Java中的txt文件中获取引号之间的字符串
【发布时间】:2019-08-26 17:13:38
【问题描述】:

好的,我知道有很多正则表达式问题,但感谢您抽出宝贵时间

编辑为已解决的代码

https://stackoverflow.com/a/25791942/8926366 给出了答案

我有一个包含引号的文本文件,我想将其放入ArrayList<String>。为此,我使用ScannerFile 方法,并且我想熟悉正则表达式,因为它似乎是一种非常有效的方法。除了我似乎无法让它正常工作!

我设法拼凑了以下正则表达式令牌,由我了解大约 85% 的指南和人民解决方案提供:

(?<=(["']\b))(?:(?=(\\?))\2.)*?(?=\1)现在我是这样理解的:

(?<=       # positive lookbehind group1
  (        # for this new group group2
   ["']    # the characters I am looking for
   \b      # word boundary anchor
  )        # end group2
)          # end group1
(?:        # non-capturing group3
  (?=      # lookahead group4
    (\\?)  # I still have no idea what this means exactly
  )        # end group 4
  \2       # matching the contents of the 2nd group in the expression.
)          # end group3
*?         # lazy 
(?=\1)     # look ahead for group 1

我现在确认它不起作用哈哈

但是这可行(有点,从 [\"] 中删除了 ',因为我的法文键盘,将逗号与法文引号分开会太长,在这种情况下没什么大不了的)

([\"])((?:(?=(\\?))\3.)*?)\1

带输入:

“有两件事是无限的:宇宙和人类的愚蠢;我不确定宇宙。”

“思想伟大的人,往往会犯很大的错误”——马丁·海德格尔

它给出:

有两件事是无限的:宇宙和人类的愚蠢;我不确定宇宙。

思想伟大的人,往往会犯很大的错误

对于所有对为什么他们的正则表达式不适用于 txt 文件感到困惑的人 - 尝试使用 notepad++ 或其他东西来替换所有各种可能的引号(确保检查结束字符和开始字符!)用一种引号

方法如下:(现在效果很好)


  public class WitticismFileParser {

   ArrayList<String> witticisms;
   Scanner scan;
   String regex="([\"])((?:(?=(\\\\?))\\3.)*?)\\1"; //"(?s)([\"])((?<quotedText>(?=(\\\\?))\\3.)*?)(?<[\"])";
   public ArrayList<String> parse(String FILE_PATH){

       witticisms = new ArrayList<>();
       Pattern pattern = Pattern.compile(regex);


       try{
           File txt= new File(FILE_PATH);
           scan= new Scanner(txt);
           String line="";
           Matcher matcher;
           matcher=pattern.matcher(line);

           while(scan.hasNext()){
               line=scan.nextLine();
               matcher=matcher.reset(line);

               if (matcher.find()){
                   line=matcher.group(2);
                   witticisms.add(line);
                   System.out.println(line);
               }

           }

       }catch(IOException e){
           System.err.println("IO Exception- "+ e.getMessage());
           e.printStackTrace();

       }catch(Exception e){
           System.err.println("Exception- "+e.getMessage());
           e.printStackTrace();
       }finally{
           if(scan!=null)
               scan.close();       
       }

       return witticisms;
   }

}

在此处留下故障排除

当我在扫描仪得到它时直接让它打印线时,我看到输入文本符合预期。我确保重新格式化 .txt 以便所有引号都相同

无论如何,感谢您对此的任何帮助,阅读正则表达式文档让我头疼不已

感谢任何回答的人!

【问题讨论】:

  • (\?) 将单个问号匹配为捕获的组。 \ 用于转义?,因为? 是一个正则表达式标记
  • 我怀疑我是否能真正理解您的问题,但让我们尝试一种解决方案:find() 方法将字符串的匹配部分向前移动一步。然后根据我自己的经验,检查您是否在监视的变量中调用了 find 方法。如果是,则被监视的变量将光标向前移动,然后您将面临异常。
  • 正如@Matt.G 所指出的 (\\?) 匹配并捕获单个文字问号。 \\是改变字面意思\的意思。否则它将捕获文字反斜杠以及文字问号。是的,当您尝试学习正则表达式时,可能会让您头晕目眩,但它确实是一个强大的工具。
  • 仅供参考:小心浏览器不兼容问题。例如,正向回溯不适用于 Microsoft Edge 上的 Java/JavaScript,但适用于 Google Chrome。
  • 好的,这里有一些信息。这个(?:(?=(\\?))\1.)*? 夹在任何东西之间,匹配一切。它大致相当于.*?。你有什么问题?

标签: java regex


【解决方案1】:

为什么不简单地使用下面的正则表达式?

"(?<textBetweenQuotes>[\s\S]*?)"

" matches the character " literally.
(?<textBetweenQuotes> is the start of a named capture group.
[\s\S]*? matches any character including newlines between zero or an infinite amount of times but lazily (so stopping as soon as possible).
) is the end of the named capture group.
" matches the character " literally.

如果你不能在你的程序中使用命名的捕获组,你总是可以使用下面的正则表达式而不用它并替换它的引号。

"[\s\S]*?"

【讨论】:

  • 我可能会尝试将其放在环视之间,谢谢您的建议
猜你喜欢
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
  • 2011-07-17
  • 2010-09-29
相关资源
最近更新 更多