据我所知,Dart 不支持字素集群,尽管有人说支持它:
在实现之前,我有哪些用于迭代字素集群的选项?例如,如果我有这样的字符串:
String family = '\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}'; // ???
String myString = 'Let me introduce my $family to you.';
并且在五码点家族表情符号之后有一个光标:
如何将光标向左移动一个用户感知的字符?
(在这种特殊情况下,我知道字素簇的大小,所以我可以做到,但我真正要问的是找到任意长的字素簇的长度。)
更新
我从 this article 看到Swift 使用系统的 ICU图书馆。在 Flutter 中可能会出现类似的情况。
对于那些想玩弄我上面的例子的人,这里有一个演示项目。按钮将光标向右或向左移动。目前需要按 8 次按钮才能将光标移过家庭表情符号。
main.dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Grapheme cluster testing')),
body: BodyWidget(),
),
);
}
}
class BodyWidget extends StatefulWidget {
@override
_BodyWidgetState createState() => _BodyWidgetState();
}
class _BodyWidgetState extends State<BodyWidget> {
TextEditingController controller = TextEditingController(
text: 'Let me introduce my \u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467} to you.'
);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
TextField(
controller: controller,
),
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text('<<'),
onPressed: () {
_moveCursorLeft();
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text('>>'),
onPressed: () {
_moveCursorRight();
},
),
),
],
)
],
);
}
void _moveCursorLeft() {
int currentCursorPosition = controller.selection.start;
if (currentCursorPosition == 0)
return;
int newPosition = currentCursorPosition - 1;
controller.selection = TextSelection(baseOffset: newPosition, extentOffset: newPosition);
}
void _moveCursorRight() {
int currentCursorPosition = controller.selection.end;
if (currentCursorPosition == controller.text.length)
return;
int newPosition = currentCursorPosition + 1;
controller.selection = TextSelection(baseOffset: newPosition, extentOffset: newPosition);
}
}
最佳答案
更新:使用 https://pub.dartlang.org/packages/icu
示例代码:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:icu/icu.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Grapheme cluster testing')),
body: BodyWidget(),
),
);
}
}
class BodyWidget extends StatefulWidget {
@override
_BodyWidgetState createState() => _BodyWidgetState();
}
class _BodyWidgetState extends State<BodyWidget> {
final ICUString icuText = ICUString('Let me introduce my \u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467} to you.\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}');
TextEditingController controller;
_BodyWidgetState() {
controller = TextEditingController(
text: icuText.toString()
);
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
TextField(
controller: controller,
),
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text('<<'),
onPressed: () async {
await _moveCursorLeft();
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text('>>'),
onPressed: () async {
await _moveCursorRight();
},
),
),
],
)
],
);
}
void _moveCursorLeft() async {
int currentCursorPosition = controller.selection.start;
if (currentCursorPosition == 0)
return;
int newPosition = await icuText.previousGraphemePosition(currentCursorPosition);
controller.selection = TextSelection(baseOffset: newPosition, extentOffset: newPosition);
}
void _moveCursorRight() async {
int currentCursorPosition = controller.selection.end;
if (currentCursorPosition == controller.text.length)
return;
int newPosition = await icuText.nextGraphemePosition(currentCursorPosition);
controller.selection = TextSelection(baseOffset: newPosition, extentOffset: newPosition);
}
}
原答案:
在 Dart/Flutter 完全实现 ICU 之前,我认为最好的选择是使用 PlatformChannel传递 Unicode 字符串 native(iOS Swift4+ 或 Android Java/Kotlin)在那里迭代/操作,然后发回结果。
BreakIterator 替换为 ICU library的,效果更好。除了导入语句之外没有任何变化。我建议使用原生操作(而不是在 Dart 上使用)的原因是因为 Unicode 有太多的事情要处理,例如规范化、规范等价、ZWNJ、ZWJ、ZWSP 等。
如果您需要一些示例代码,请在下方评论。
关于unicode - 在 Dart 中处理字素簇,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54483177/
在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby-vips的github页面上的链接,我们将不胜感激!如果有ruby-
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
我遇到了一个非常困难的时期:#containedwithin:"MA\u008EEIKIAI"#shouldbe"MAŽEIKIAI"#natureofstring$pstring3"MA\u008EEIKIAI"$putsstring3MAEIKIAI$string3.inspect"\"MA\\u008EEIKIAI\""$string3.bytes#关于从哪里开始的任何想法?注意:这不是我的previousquestion的副本. 最佳答案 \u008E表示代码点为8e(十六进制)的unicode字符出现在字符串中的那个位置。
我查看了Stripedocumentationonerrors,但我仍然无法正确处理/重定向这些错误。基本上无论发生什么,我都希望他们返回到edit操作(通过edit_profile_path)并向他们显示一条消息(无论成功与否)。我在edit操作上有一个表单,它可以POST到update操作。使用有效的信用卡可以正常工作(费用在Stripe仪表板中)。我正在使用Stripe.js。classExtrasController5000,#amountincents:currency=>"usd",:card=>token,:description=>current_user.email)
不幸的是,Unicode0.1(sudogeminstallunicode)不能在Ruby1.9上运行。我有以下片段:require"rubygems"require"unicode"str="áéíóúç"Unicode.normalize_KD(str).gsub(/[^\x00-\x7F]/n,"")#=>aeiouc我用它来将标题转换为永久链接,而不删除重音字符。有没有办法使用pack或unpack方法转换此类文本? 最佳答案 更新:更好的选择可能是使用gemunicode_utils这是专门为这些缺失的功能创建的:requ
我正在编写一个Rails应用程序,它需要将IDN域名从Punycode转换为它的Unicode等效项。我尝试安装idngem绑定(bind)到GNULibIDN,但它不会编译native代码。显然others与Ruby1.9.x有同样的问题。我也试过纯RubySimpleIDNgem,但我更喜欢本地的东西。 最佳答案 试试simpleidngem.它适用于Ruby1.8.7和1.9.2。编辑你的Gemfile:gem'simpleidn'然后可以输入如下命令:SimpleIDN.to_unicode("xn--mllerriis-l
当profile为nil时,总是让我感到悲伤...我该怎么办? 最佳答案 在View中使用变量之前,始终检查变量是否为nil。我确信这个问题有更优雅的解决方案,但这应该能让您入门。 关于ruby-on-rails-Rails处理.Erb与Nils,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/2709605/