String 如何拆分多个连词?
我有一个大约1000个条目的数组,示例如下:String 如何拆分多个连词?,string,nlp,String,Nlp,我有一个大约1000个条目的数组,示例如下: wickedweather liquidweather driveourtrucks gocompact slimprojector 我希望能够将其分为以下几个词: wicked weather liquid weather drive our trucks go compact slim projector 我希望我的正则表达式能起作用。但是,既然没有边界可停,也没有任何形式的大写字母可供我输入,我想,可能有必要参考字典 我想它可以手工完成,但
wickedweather
liquidweather
driveourtrucks
gocompact
slimprojector
我希望能够将其分为以下几个词:
wicked weather
liquid weather
drive our trucks
go compact
slim projector
我希望我的正则表达式能起作用。但是,既然没有边界可停,也没有任何形式的大写字母可供我输入,我想,可能有必要参考字典
我想它可以手工完成,但为什么-当它可以用代码完成时!=)但这让我感到困惑。有什么想法吗 我认为你认为这不是正则表达式的工作,这是对的。我会使用字典的思想来处理这个问题——在字典中查找单词的最长前缀。当你找到它时,把它切掉,然后用剩下的绳子做同样的事情
上述方法存在歧义,例如“DriveRealFast”会首先找到“driver”,然后遇到“eallyfast”问题。因此,如果遇到这种情况,您还必须进行一些回溯。或者,由于您没有那么多字符串要拆分,只需手动执行自动拆分失败的字符串即可。好吧,仅使用正则表达式无法解决问题本身。一个解决方案(可能不是最好的)是获得一个字典,并为字典中的每个工作与列表中的每个单词进行正则表达式匹配,只要成功,就添加空格。当然这不会太快,但编程很容易,而且比手工操作要快 需要基于词典的解决方案。如果你有一个有限的单词词典,这可能会被简化,否则,构成其他单词前缀的单词将成为一个问题。我可能对此感到沮丧,但让秘书来做这件事 您将在字典解决方案上花费比手动处理更多的时间。此外,您可能对解决方案没有100%的信心,因此您仍然需要手动关注它。人类可以做到吗 farsidebag far sidebag farside bag far side bag 远侧袋 远侧袋 远侧袋 远侧袋 你不仅需要使用字典,还可能需要使用统计方法来找出最有可能的(或者,上帝禁止,你选择的人类语言的实际HMM…) 关于如何进行可能有用的统计,我请Peter Norvig博士谈谈,他在21行代码中解决了一个不同但相关的拼写检查问题: (他确实有点作弊,把每个for循环折叠成一行……但仍然如此) 更新这个卡在我的脑子里了,所以我今天不得不把它生下来。这段代码与Robert Gamble描述的代码进行了类似的拆分,但随后它根据提供的字典文件中的词频对结果进行排序(现在应该是一些代表您的域或英语的文本。我使用了Norvig的big.txt,上面链接了,并向它添加了一本字典,以覆盖缺少的单词) 两个单词的组合在大多数情况下会超过三个单词的组合,除非频率差异很大
我在博客上发布了这段代码,并做了一些小改动 并在代码中写了一些关于底流错误的内容。。我很想安静地修复它,但我想这可能会帮助一些以前没有见过日志技巧的人:
输出您的文字,再加上我自己的一些文字——注意“orcore”会发生什么: perl splitwords.pl big.txt单词 答案:2种可能性 -小牛肉 -答案:艾尔 wickedweather:4种可能性 -恶劣天气 -我们嘲笑她 -灯芯天气 -我们对她怒目而视 液体天气:6种可能性 -流质天气 -我们看着她 -晴朗的天气 -我们看了她一眼 -李渠天气预报 -李渠:我们在看她吗 驾驶我们的卡车:1种可能性 -开我们的卡车 gocompact:1种可能性 -紧凑型 slimprojector:2种可能性 -超薄投影仪 -苗条项目或 orcore:3种可能性 -或核心 -或co re -兽人矿石 代码:
#/usr/bin/env perl
严格使用;
使用警告;
子查找_匹配项($);
子查找匹配记录($\@);
子查找单词顺序分数(@);
sub get_word_统计数据($);
子打印结果(美元);
子用法();
我们的百分比(%DICT,$TOTAL);
{
my($dict_file,$word_file)=@ARGV;
($dict_file&&$word_file)或die(用法);
{
我的$DICT;
($DICT,$TOTAL)=获取单词统计数据($DICT\u文件);
%DICT=%$DICT;
}
{
打开(my$WORDS,这里最好的工具是递归,而不是正则表达式。基本思想是从字符串的开头开始寻找一个单词,然后从字符串的其余部分寻找另一个单词,依此类推,直到字符串的结尾。递归解决方案是自然的,因为需要进行回溯n当字符串的给定剩余部分无法拆分为一组单词时。下面的解决方案使用字典确定单词,并在找到它们时打印出解决方案(一些字符串可以拆分为多个可能的单词集,例如,wickedweather可以解析为“邪恶的我们看着她”)。如果您只需要一组单词,则需要确定选择最佳单词集的规则,方法可能是选择单词数最少的解决方案或设置最小单词长度
#!/usr/bin/perl
use strict;
my $WORD_FILE = '/usr/share/dict/words'; #Change as needed
my %words; # Hash of words in dictionary
# Open dictionary, load words into hash
open(WORDS, $WORD_FILE) or die "Failed to open dictionary: $!\n";
while (<WORDS>) {
chomp;
$words{lc($_)} = 1;
}
close(WORDS);
# Read one line at a time from stdin, break into words
while (<>) {
chomp;
my @words;
find_words(lc($_));
}
sub find_words {
# Print every way $string can be parsed into whole words
my $string = shift;
my @words = @_;
my $length = length $string;
foreach my $i ( 1 .. $length ) {
my $word = substr $string, 0, $i;
my $remainder = substr $string, $i, $length - $i;
# Some dictionaries contain each letter as a word
next if ($i == 1 && ($word ne "a" && $word ne "i"));
if (defined($words{$word})) {
push @words, $word;
if ($remainder eq "") {
print join(' ', @words), "\n";
return;
} else {
find_words($remainder, @words);
}
pop @words;
}
}
return;
}
!/usr/bin/perl
严格使用;
我的$WORD_文件='/usr/share/dict/words';#根据需要更改
我的%words;#字典中的单词散列
#打开字典,将单词加载到哈希中
打开(WORDS,$WORD\u文件)或死亡“无法打开字典:$!\n”;
而(){
咀嚼;
$words{lc($)}=1;
}
近(字);
#从stdin中一次读一行,分成几个单词
而(){
咀嚼;
我的文字;
查找单词(lc($);
}
子查找单词{
#打印所有可以将$string解析为完整单词的方式
我的$string=shift;
我的"文字",;
my$length=长度$string;
#!/usr/bin/env perl
use strict;
use warnings;
sub find_matches($);
sub find_matches_rec($\@\@);
sub find_word_seq_score(@);
sub get_word_stats($);
sub print_results($@);
sub Usage();
our(%DICT,$TOTAL);
{
my( $dict_file, $word_file ) = @ARGV;
($dict_file && $word_file) or die(Usage);
{
my $DICT;
($DICT, $TOTAL) = get_word_stats($dict_file);
%DICT = %$DICT;
}
{
open( my $WORDS, '<', $word_file ) or die "unable to open $word_file\n";
foreach my $word (<$WORDS>) {
chomp $word;
my $arr = find_matches($word);
local $_;
# Schwartzian Transform
my @sorted_arr =
map { $_->[0] }
sort { $b->[1] <=> $a->[1] }
map {
[ $_, find_word_seq_score(@$_) ]
}
@$arr;
print_results( $word, @sorted_arr );
}
close $WORDS;
}
}
sub find_matches($){
my( $string ) = @_;
my @found_parses;
my @words;
find_matches_rec( $string, @words, @found_parses );
return @found_parses if wantarray;
return \@found_parses;
}
sub find_matches_rec($\@\@){
my( $string, $words_sofar, $found_parses ) = @_;
my $length = length $string;
unless( $length ){
push @$found_parses, $words_sofar;
return @$found_parses if wantarray;
return $found_parses;
}
foreach my $i ( 2..$length ){
my $prefix = substr($string, 0, $i);
my $suffix = substr($string, $i, $length-$i);
if( exists $DICT{$prefix} ){
my @words = ( @$words_sofar, $prefix );
find_matches_rec( $suffix, @words, @$found_parses );
}
}
return @$found_parses if wantarray;
return $found_parses;
}
## Just a simple joint probability
## assumes independence between words, which is obviously untrue
## that's why this is broken out -- feel free to add better brains
sub find_word_seq_score(@){
my( @words ) = @_;
local $_;
my $score = 1;
foreach ( @words ){
$score = $score * $DICT{$_} / $TOTAL;
}
return $score;
}
sub get_word_stats($){
my ($filename) = @_;
open(my $DICT, '<', $filename) or die "unable to open $filename\n";
local $/= undef;
local $_;
my %dict;
my $total = 0;
while ( <$DICT> ){
foreach ( split(/\b/, $_) ) {
$dict{$_} += 1;
$total++;
}
}
close $DICT;
return (\%dict, $total);
}
sub print_results($@){
#( 'word', [qw'test one'], [qw'test two'], ... )
my ($word, @combos) = @_;
local $_;
my $possible = scalar @combos;
print "$word: $possible possibilities\n";
foreach (@combos) {
print ' - ', join(' ', @$_), "\n";
}
print "\n";
}
sub Usage(){
return "$0 /path/to/dictionary /path/to/your_words";
}
#!/usr/bin/perl
use strict;
my $WORD_FILE = '/usr/share/dict/words'; #Change as needed
my %words; # Hash of words in dictionary
# Open dictionary, load words into hash
open(WORDS, $WORD_FILE) or die "Failed to open dictionary: $!\n";
while (<WORDS>) {
chomp;
$words{lc($_)} = 1;
}
close(WORDS);
# Read one line at a time from stdin, break into words
while (<>) {
chomp;
my @words;
find_words(lc($_));
}
sub find_words {
# Print every way $string can be parsed into whole words
my $string = shift;
my @words = @_;
my $length = length $string;
foreach my $i ( 1 .. $length ) {
my $word = substr $string, 0, $i;
my $remainder = substr $string, $i, $length - $i;
# Some dictionaries contain each letter as a word
next if ($i == 1 && ($word ne "a" && $word ne "i"));
if (defined($words{$word})) {
push @words, $word;
if ($remainder eq "") {
print join(' ', @words), "\n";
return;
} else {
find_words($remainder, @words);
}
pop @words;
}
}
return;
}
>>> viterbi_segment('wickedweather')
(['wicked', 'weather'], 5.1518198982768158e-10)
>>> ' '.join(viterbi_segment('itseasyformetosplitlongruntogetherblocks')[0])
'its easy for me to split long run together blocks'
# spiral mStartCData nonnegativedecimaltype getUtf8Octets GPSmodule savefileas nbrOfbugs
mStartCData: ['m', 'Start', 'C', 'Data']
nonnegativedecimaltype: ['nonnegative', 'decimal', 'type']
getUtf8Octets: ['get', 'Utf8', 'Octets']
GPSmodule: ['GPS', 'module']
savefileas: ['save', 'file', 'as']
nbrOfbugs: ['nbr', 'Of', 'bugs']
# spiral wickedweather liquidweather driveourtrucks gocompact slimprojector
wickedweather: ['wicked', 'weather']
liquidweather: ['liquid', 'weather']
driveourtrucks: ['driveourtrucks']
gocompact: ['go', 'compact']
slimprojector: ['slim', 'projector']
from mlmorph import Analyser
analyser = Analyser()
analyser.analyse("കേരളത്തിന്റെ")
[('കേരളം<np><genitive>', 179)]
$ echo thisisatest | python -m wordsegment
this is a test
>>> import wordninja
>>> wordninja.split('bettergood')
['better', 'good']
function spinalCase(str) {
let lowercase = str.trim()
let regEx = /\W+|(?=[A-Z])|_/g
let result = lowercase.split(regEx).join("-").toLowerCase()
return result;
}
spinalCase("AllThe-small Things");
static List<String> wordBreak(
String input,
Set<String> dictionary
) {
List<List<String>> result = new ArrayList<>();
List<String> r = new ArrayList<>();
helper(input, dictionary, result, "", 0, new Stack<>());
for (List<String> strings : result) {
String s = String.join(" ", strings);
r.add(s);
}
return r;
}
static void helper(
final String input,
final Set<String> dictionary,
final List<List<String>> result,
String state,
int index,
Stack<String> stack
) {
if (index == input.length()) {
// add the last word
stack.push(state);
for (String s : stack) {
if (!dictionary.contains(s)) {
return;
}
}
result.add((List<String>) stack.clone());
return;
}
if (dictionary.contains(state)) {
// bifurcate
stack.push(state);
helper(input, dictionary, result, "" + input.charAt(index),
index + 1, stack);
String pop = stack.pop();
String s = stack.pop();
helper(input, dictionary, result, s + pop.charAt(0),
index + 1, stack);
}
else {
helper(input, dictionary, result, state + input.charAt(index),
index + 1, stack);
}
return;
}