Language agnostic 拆分字符串时忽略带引号的部分
给定如下字符串: a、 “字符串,带”,各种,“值和一些”,引用 在忽略引用部分中的逗号的情况下,什么是一种基于逗号分割的好算法 输出应该是一个数组: [“a”,“string,with”,“variable”,“value,and some”,“quoted”]Language agnostic 拆分字符串时忽略带引号的部分,language-agnostic,parsing,csv,Language Agnostic,Parsing,Csv,给定如下字符串: a、 “字符串,带”,各种,“值和一些”,引用 在忽略引用部分中的逗号的情况下,什么是一种基于逗号分割的好算法 输出应该是一个数组: [“a”,“string,with”,“variable”,“value,and some”,“quoted”] 当然,使用CSV解析器更好,但为了好玩,您可以: Loop on the string letter by letter. If current_letter == quote : toggle inside
当然,使用CSV解析器更好,但为了好玩,您可以:
Loop on the string letter by letter.
If current_letter == quote :
toggle inside_quote variable.
Else if (current_letter ==comma and not inside_quote) :
push current_word into array and clear current_word.
Else
append the current_letter to current_word
When the loop is done push the current_word into array
作者在这里插入了一块C代码,用于处理您遇到问题的场景:
不应该太难翻译。
< P>如果我的选择语言没有提供一种方法而不用思考,那么我会首先考虑两种选择,作为简单的出路:然而,这些都是黑客行为,如果这是一个纯粹的“心理”练习,那么我怀疑它们将证明毫无用处。如果这是一个真实的问题,那么了解该语言将有助于我们提供一些具体的建议。我用它来解析字符串,不确定它是否有帮助;但也许需要一些小的修改
function getstringbetween($string, $start, $end){
$string = " ".$string;
$ini = strpos($string,$start);
if ($ini == 0) return "";
$ini += strlen($start);
$len = strpos($string,$end,$ini) - $ini;
return substr($string,$ini,$len);
}
$fullstring = "this is my [tag]dog[/tag]";
$parsed = getstringbetween($fullstring, "[tag]", "[/tag]");
echo $parsed; // (result = dog)
/mp这里有一个简单的算法:
#逗号#
标记引用的逗号
- 如果输入以“”开头,请在数组中标记索引%2==0的项目
- 否则,请标记数组中索引%2==1的项目
”和“
字符分隔#逗号#
占位符数组中的所有实例替换为,'
字符(固定为处理“a,b”,c,“d,e,f,h”,“i,j,k”)
这是一个标准的CSV风格的解析。很多人都尝试用正则表达式来实现这一点。使用正则表达式可以达到90%左右的解析率,但您确实需要一个真正的CSV解析器来正确完成。几个月前我发现了一个我极力推荐的方法!这里有一个伪代码(也称为Python)一次性实现:-p
def parsecsv(instr):
i=0
j=0
超出额=[]
#我是固定的,直到匹配发生,然后它前进
#每次通过以下通道向前移动最大j.j英寸:
而我2且s[0]=''”,且s[-1]=''”:
s=s[1:-1]
#将其添加到结果中
未完成追加
#跳过逗号,向上移动i(到何处
#j将在迭代结束时)
i=j+1
j=j+1
回击出局者
def测试用例(仪表,预期):
outstr=parsecsv(instr)
打印输出
断言应为==outsr
#不会处理像“1,2”,a,b,c,d,2”或
#转义引号,但是可以很容易地添加这些引号。
测试用例('a,b,“1,2,3”,c',['a','b','1,2,3','c'])
测试用例('a,b,“1,2,3”,c',['a','b','1,2,3','c'])
#奇数引号表示“不匹配引号”异常
#测试用例('a,b,“1,2,3”,“c”,“a”,“b”,“1,2,3”,“c']))
看起来您在这里找到了一些不错的答案
对于那些希望处理自己的CSV文件解析的人,请听取专家和管理员的建议
您的第一个想法是,“我需要在引号中处理逗号。”
你的下一个想法是,“哦,废话,我需要处理引号内的引号。转义引号。双引号。单引号…”
这是一条疯狂之路。不要自己写。找到一个具有广泛单元测试覆盖率的库,该库覆盖了所有困难的部分,并且为您经历了地狱。对于.NET,请使用免费库。我忍不住想看看是否可以在Python一行程序中使用它:
arr = [i.replace("|", ",") for i in re.sub('"([^"]*)\,([^"]*)"',"\g<1>|\g<2>", str_to_test).split(",")]
arr=[i.replace(“;”,“,”)代表re.sub中的i(“([^”]*)\,([^”]*)”,“\g | \g”,stru to_test)。拆分(“,”)
返回['a','string,带','各种','值和一些','引号']
它首先将“,”内引号替换为另一个分隔符(|),
在“,”上拆分字符串并再次替换|分隔符。Python:
import csv
reader = csv.reader(open("some.csv"))
for row in reader:
print row
如果出现奇数引号怎么办 在原始字符串中 这看起来很像CSV解析,它在处理带引号的字段时有一些特殊性。仅当字段用双引号分隔时,才会转义该字段,因此: 字段1,“字段2,字段3”,字段4,“字段5,字段6”字段7 变成 字段1 场2,场3 字段4 “第5场 字段6“字段7 请注意,如果它不是以引号开始和结束,那么它就不是一个带引号的字段,双引号被简单地视为双引号 顺便说一句,如果我没记错的话,我链接到的代码实际上没有正确处理这个问题。这里有一个简单的pytho
arr = [i.replace("|", ",") for i in re.sub('"([^"]*)\,([^"]*)"',"\g<1>|\g<2>", str_to_test).split(",")]
import csv
reader = csv.reader(open("some.csv"))
for row in reader:
print row
def splitIgnoringSingleQuote(string, split_char, remove_quotes=False):
string_split = []
current_word = ""
inside_quote = False
for letter in string:
if letter == "'":
if not remove_quotes:
current_word += letter
if inside_quote:
inside_quote = False
else:
inside_quote = True
elif letter == split_char and not inside_quote:
string_split.append(current_word)
current_word = ""
else:
current_word += letter
string_split.append(current_word)
return string_split
def find_character_indices(s, ch):
return [i for i, ltr in enumerate(s) if ltr == ch]
def split_text_preserving_quotes(content, include_quotes=False):
quote_indices = find_character_indices(content, '"')
output = content[:quote_indices[0]].split()
for i in range(1, len(quote_indices)):
if i % 2 == 1: # end of quoted sequence
start = quote_indices[i - 1]
end = quote_indices[i] + 1
output.extend([content[start:end]])
else:
start = quote_indices[i - 1] + 1
end = quote_indices[i]
split_section = content[start:end].split()
output.extend(split_section)
output += content[quote_indices[-1] + 1:].split()
return output