Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 列表识别与解析算法_Java_Python_List_Parsing - Fatal编程技术网

Java 列表识别与解析算法

Java 列表识别与解析算法,java,python,list,parsing,Java,Python,List,Parsing,我的数据理论上是一个列表,但从历史上看,它是由用户作为一个自由格式的文本字段输入的。现在,我需要将列表中的每个项目分开,以便可以分析每个元素 用户输入的我的数据的简化示例: one, two, three, four, five one. two. three, four. five. "I start with one, then do two, maybe three and four then five" one two three four five. on

我的数据理论上是一个列表,但从历史上看,它是由用户作为一个自由格式的文本字段输入的。现在,我需要将列表中的每个项目分开,以便可以分析每个元素

用户输入的我的数据的简化示例:

one, two, three, four, five 

one. two. three, four. five.

"I start with one, then do two, maybe three and four then five"

one  
two  
three  
four  
five.  

one, two. three four five

one two three four - five

"not even a list, no list-elements here! but list item separators may appear. grrr"
所以,这或多或少就是数据的样子。实际上,一个列表项可能有好几个单词长。我需要处理这些列表(其中有数千个),以便最终得到如下数组:

array[0] = "one"  
array[1] = "two"  
array[n] = n  
我承认有时我的算法会完全无法解析列表,我不需要100%的成功率,75%就好了。误报对我来说是非常昂贵的,所以我宁愿完全拒绝一个列表,也不愿生成一个不包含真实数据的列表——假设一些用户输入了无意义的胡言乱语

我有一些想法,可以尝试确定使用了哪些分隔符,以及与内容大小相关的数据分隔规则


我更喜欢Java或Python,但是任何解决方案都是受欢迎的:-)

在Java中,字符串标记器将实现这一点(即StringTokenizer(inputString,delimiterList))

印刷品

A

B

C

D

以下命令将把输入字符串“解析”为由非单词字符分隔的“单词”字符序列

String input = ...
String[] parts = input.split("[^\w]*");
我不知道你怎么区分一张清单和胡言乱语。我想你需要进一步解释你的问题领域

编辑:如果你不能定义你(作为一个人)用来区分列表和胡言乱语的规则,那么这个问题基本上是无法解决的。你知道,计算机不会变魔术


也许你应该用这个程序来处理那些“绝对”列表的子集,然后手工对其他的列表进行分类。

我不知道我是否理解你的问题。如果您想从python中混乱的字符串中提取字母数字字符串,那么应该是:

>>> import re
>>> re.split('\W+','abaa, asodf ?. poasid - paosfi sec')
['abaa', 'asodf', 'poasid', 'paosfi', 'sec']
或者,如果您知道分隔符:

>>> re.split('[,. -]+','abaa, asodf, poasid - paosfi sec')
['abaa', 'asodf', 'poasid', 'paosfi', 'sec']

如果你不能定义你的数据(“单词可以是任何东西,我无法事先知道任何单个列表可以包含什么。它们不仅仅是数字……它可能是任何东西的列表”),那么你就有严重的问题

具体来说,如果您不能定义数据,您的问题就无法解决

你可以试着玩

你可以丢弃“噪音词”(“,”,“,”,“,”我“,”开始“,”用“,”然后“,”做“,”等等),剩下的可能是这个不可定义的“词可以是剩下的任何东西”


除非你能更好地定义你的数据,否则你可能注定要经历很多挣扎。

解决这个问题的第一步是详细分析人类是如何解决这个问题的。我将把这个问题分成两部分

  • 人类如何区分列表和非列表?例如,是否因为非列表是语法英语句子?如果是这样,您可以使用一个可用的自然语言处理工具包来区分列表和非列表

  • 人类如何识别列表中的分隔符和列表元素?例如,他们是否因为某些特定的领域知识而识别列表元素?或者他们只是识别一小部分公共分隔符中的一个?列表元素总是单个单词吗?如果不是,在什么情况下它们是多个单词

  • 我还将仔细查看数百个示例,看看是否有任何可以轻松识别和解析的通用模式。例如,如果30%的条目是简单的逗号分隔列表,那么正则表达式将很容易地识别和解析它们。也许一个小的正则表达式集将处理大部分语料库


    最后,我假设当前数据不仅被人类输入和识别,而且被人类消费。您将项目分解为列表的原因是为了将人从循环中移除,还是为了让他们的工作更轻松?如果是后者,我建议为他们提供分解列表元素,并作为备份,提供最初输入的文本。换言之,如果你做错了,就要对冲赌注。

    要么你知道你的单词词典,要么你有列表分隔符的优先顺序。否则,这个问题的定义太模糊,计算机无法处理

    我想你的优先顺序可以是逗号,点,连字符,空格。因此,这意味着您可以使用逗号进行拆分,而不是使用点等进行拆分


    或者,您可以继续按每个连续的分隔符进行拆分,直到找到文本中不存在的分隔符。

    我不确定最佳答案到底是什么,但如果您需要很少的误报,那么您可能应该定义一些很可能是列表的模式,并严格拒绝所有其他数据

    patterns = [
        re.compile(r'^\s*(\w+)(\s*,\s*(\w+))*\s*$'), 
        re.compile(r'^\s*(\w+)(\s*\.\s*(\w+))*\s*$'), 
        re.compile(r'^\s*(\w+)(\s*,\s*(\w+))*\s+and\s+(\w+)\s*^$')
    ]
    acceptSet = [ line for line in candidateSet if 
                  any(pattern.match(line) for pattern in patterns)] 
    

    与其关注代码,不如关注方法。根据斯威尔登说的做一点准备

    如果您的列表被人类用户使用,您可以要求他们在您出错时纠正您(此纠正对输入文本的用户或稍后查看文本的用户可见)。如果一个给定的输入看起来很像一个列表,但还不足以确定,你可以向他们显示列表和原始输入,并让他们选择

    要将输入自动分类为列表或文本,您可以创建多个度量标准,以便根据这些标准做出决策:

    • 给定分隔符(即
      [“”、\t'、“、”、“、”、“、”和“]
      ),该短语使用多少个分隔符?期待一两个。哪一个
    • 是由片段组成的输入(使用某种语法系统)-片段倾向于表示列表
    • 此输入字段(或输入中的上下文)是否倾向于包含列表项
    • 列表中的单词本身(有些单词可能总是表示您所在领域中的一个句子或列表)
    然后将此信息传递给int
    patterns = [
        re.compile(r'^\s*(\w+)(\s*,\s*(\w+))*\s*$'), 
        re.compile(r'^\s*(\w+)(\s*\.\s*(\w+))*\s*$'), 
        re.compile(r'^\s*(\w+)(\s*,\s*(\w+))*\s+and\s+(\w+)\s*^$')
    ]
    acceptSet = [ line for line in candidateSet if 
                  any(pattern.match(line) for pattern in patterns)] 
    
    rawdata = """\
    one, two, three, four, five
    one. two. three, four. five.
    "I start with one, then do two, maybe three and four then five"
    one  
    two  
    three  
    four  
    five.  
    one, two. three four five
    one two three four - five
    "not even a list, no list-elements here! but list item separators may appear. grrr"
    a dog with a bone is a beautiful twosome""".splitlines()
    
    from pyparsing import oneOf, WordStart, CharsNotIn, alphas, LineEnd
    options = (WordStart() + oneOf("one two three four five") + (CharsNotIn(alphas)|LineEnd()))
    
    for userinput in rawdata:
        print userinput
        print [opt[0] for opt in options.searchString(userinput)]
        print
    
    one, two, three, four, five
    ['one', 'two', 'three', 'four', 'five']
    
    one. two. three, four. five.
    ['one', 'two', 'three', 'four', 'five']
    
    "I start with one, then do two, maybe three and four then five"
    ['one', 'two', 'three', 'four', 'five']
    
    one  
    ['one']
    
    two  
    ['two']
    
    three  
    ['three']
    
    four  
    ['four']
    
    five.  
    ['five']
    
    one, two. three four five
    ['one', 'two', 'three', 'four', 'five']
    
    one two three four - five
    ['one', 'two', 'three', 'four', 'five']
    
    "not even a list, no list-elements here! but list item separators may appear. grrr"
    []
    
    a dog with a bone is a beautiful twosome
    []