BreakIterator 在 Android 中如何工作?

2024-04-08

我正在 Android 中制作自己的文本处理器(蒙古语的自定义垂直脚本 TextView)。我以为我必须自己找到所有换行位置,以便我可以实现换行,但后来我发现BreakIterator https://developer.android.com/reference/java/text/BreakIterator.html。这似乎找到了各种语言中的字符、单词、行和句子之间所有可能的断点。

我正在尝试学习如何使用它。这文档 https://developer.android.com/reference/java/text/BreakIterator.html比平均水平更有帮助,但仅仅阅读仍然很难理解。我还找到了一些教程(参见here http://tutorials.jenkov.com/java-internationalization/breakiterator.html, here https://javabeanz.wordpress.com/2009/02/21/working-with-text-in-java-using-breakiterator-api/, and here https://kodejava.org/how-do-i-breaks-a-text-or-sentence-into-words/)但他们缺乏我正在寻找的输出的完整解释。

我添加这个问答风格的答案是为了帮助自己学习如何使用BreakIterator.

除了 Java 之外,我还将其设为 Android 标签,因为有显然有些区别 https://stackoverflow.com/questions/41270091/breakiterator-in-android-counts-character-wrongly它们之间。此外,Android 现在支持ICU BreakIterator https://developer.android.com/reference/android/icu/text/BreakIterator.html未来的答案可能会涉及这个问题。


BreakIterator可用于查找字符、单词、行和句子之间可能的中断。这对于诸如在可见字符之间移动光标、双击选择单词、三次单击选择句子以及换行等操作非常有用。

样板代码

下面的示例中使用了以下代码。只需调整第一部分即可更改文本和类型BreakIterator.

// change these two lines for the following examples
String text = "This is some text.";
BreakIterator boundary = BreakIterator.getCharacterInstance();

// boiler plate code
boundary.setText(text);
int start = boundary.first();
for (int end = boundary.next(); end != BreakIterator.DONE; end = boundary.next()) {
    System.out.println(start + " " + text.substring(start, end));
    start = end;
}

如果您只是想测试一下,可以将其直接粘贴到 Activity 的onCreate在安卓中。我在用着System.out.println而不是Log因此它也可以在纯 Java 环境中进行测试。

我正在使用java.text.BreakIterator而不是 ICU ,后者只能从 API 24 获得。有关更多信息,请参阅底部的链接。

人物

更改样板代码以包含以下内容

String text = "Hi 中文éé\uD83D\uDE00\uD83C\uDDEE\uD83C\uDDF3.";
BreakIterator breakIterator = BreakIterator.getCharacterInstance();

Output

0 H
1 i
2  
3 中
4 文
5 é
6 é
8 ????
10 ????????
14 .

最有趣的部分是索引6, 8, and 10。您的浏览器可能会或可能不会正确显示这些字符,但用户会将所有这些字符解释为单个字符,即使它们由多个 UTF-16 值组成。

Words

更改样板代码以包含以下内容:

String text = "I like to eat apples. 我喜欢吃苹果。";
BreakIterator boundary = BreakIterator.getWordInstance();

Output

0 I
1  
2 like
6  
7 to
9  
10 eat
13  
14 apples
20 .
21  
22 我
23 喜欢
25 吃
26 苹果
28 。

这里有一些有趣的事情需要注意。首先,在空格的两侧检测到断词。其次,尽管存在不同的语言,但多字汉字仍然被识别。即使我将语言环境设置为,在我的测试中仍然如此Locale.US.

Lines

您可以保持与 Words 示例相同的代码:

String text = "I like to eat apples. 我喜欢吃苹果。";
BreakIterator boundary = BreakIterator.getLineInstance();

Output

0 I 
2 like 
7 to 
10 eat 
14 apples. 
22 我
23 喜
24 欢
25 吃
26 苹
27 果。

请注意,中断位置不是整行文本。它们只是换行文本的方便位置。

输出与 Words 示例类似。但是,现在前面的单词包含空格和标点符号。这是有道理的,因为您不希望新行以空格或标点符号开头。另请注意,中文字符的每个字符都有换行符。这与中文多字词跨行断行是可以的一致的。

句子

更改样板代码以包含以下内容:

String text = "I like to eat apples. My email is [email protected] /cdn-cgi/l/email-protection.\n" +
        "This is a new paragraph. 我喜欢吃苹果。我不爱吃臭豆腐。";
BreakIterator boundary = BreakIterator.getSentenceInstance();

Output

0 I like to eat apples. 
22 My email is [email protected] /cdn-cgi/l/email-protection.
50 This is a new paragraph. 
75 我喜欢吃苹果。
82 我不爱吃臭豆腐。

多种语言都可以识别正确的断句。此外,电子邮件域中的点没有出现误报。

Notes

您可以设置Locale https://developer.android.com/reference/java/util/Locale.html当你创建一个BreakIterator,但如果你不这样做,它只会使用默认语言环境 https://developer.android.com/reference/java/util/Locale.html#getDefault().

进一步阅读

  • 文档 https://developer.android.com/reference/java/text/BreakIterator.html
  • BreakIterator 的 ICU 版本 https://developer.android.com/reference/android/icu/text/BreakIterator.html
  • This http://tutorials.jenkov.com/java-internationalization/breakiterator.html是更有用的教程之一。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BreakIterator 在 Android 中如何工作? 的相关文章

  • 如何查找给定字符串中仅出现一次的第一个字符[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 迭代 Sqlite-query 中的行

    我有一个表布局 我想用数据库查询的结果填充它 我使用全选 查询返回四行数据 我使用此代码来填充表行内的 TextView Cursor c null c dh getAlternative2 startManagingCursor c th
  • 测试 Hessian remoting-servlet.xml

    我们使用 Hessian 来实现富客户端和服务器之间的通信 由于移动和重命名 remoting servlet xml 中的条目有时会与实际的类名不匹配 因此 我正在寻找一种简单的方法来测试远程处理 xml 有没有简单的方法可以做到这一点
  • 如何自定义 JFrame 上的标题栏?

    我想在我的 Java Swing 桌面应用程序中拥有一个自定义的标题栏 最好的方法是什么 我可以通过在 JFrame 的构造函数中使用以下代码来使用 Swing 标题栏 this setUndecorated true this getRo
  • 具有多个注释的方法上的 AspectJ 切入点

    使用加载时编织 纯 AspectJ 我们有2个注释 Time and Count 以及一些带注释的方法 Time name myMethod1Time Count name myMethod1Count public void myMeth
  • 改变换行行为

    我可以在 TextView 中使用 Spannable 创建具有不同外观 下划线 删除线等的跨度 我怎样才能做同样的事情来改变换行行为 特别是 我不希望电子邮件地址在中间换行 我希望它像一个单词一样 I tried 包裹在一起跨度 http
  • 如何在打开导航抽屉时使背景 Activity 变小?

    我想做我的背景Activity打开时稍微小一点Navigation Drawer 模拟存在的效果Airbnb应用 我想最好的解释是截图 但重点不是让 View 变小 而是让它成为与 Drawer 打开 关闭动画同步的动画 因此 如果您开始打
  • 上传失败您应该使用 http 和 https 作为您的 Web 意图过滤器的方案

    上传失败 您应该使用 http 和 https 作为您的 Web 意图过滤器的方案 我在将免安装应用上传到 Play 商店时收到此错误 我在清单中声明了 http 和 https 的意图过滤器 如下所示
  • Guava MultiSet 与 Map?

    我对Multiset的理解是一个带有频率的集合 但是我总是可以使用Map来表示频率 还有其他原因使用Multiset吗 优点Multiset
  • 如何从 SD 卡中删除文件

    我正在创建一个文件作为电子邮件的附件发送 现在我想在发送电子邮件后删除图像 有没有办法删除文件 我努力了myFile delete 但它没有删除该文件 我在 Android 上使用此代码 因此编程语言是 Java 使用通常的 Android
  • 为什么ArrayList的非静态内部类SubList有一个成员变量“parent”?

    java util ArrayList SubList 是 java util ArrayList 的非静态内部类 这意味着它保存对其封闭类的引用 我们可以使用ArrayList this来访问java util ArrayList的成员
  • 如何在非Spring的构造型类中使用@Autowired

    我想在此类中使用该存储库 但是当我放置像 Component 这样的构造型时 我从 IDE 收到错误 无法自动装配 未找到 身份验证 类型的 bean public class CustomMethodSecurityExpressionR
  • 如何使用Android Invalidate()

    在我的主要活动中 我定义了两个视图和一个菜单 浏览次数 1 自定义视图游戏 2 按钮btn 菜单 1 打开项目用于打开文件 菜单布局在不同的活动中定义 基本上 当主活动启动时 它会绘制没有任何内容的自定义视图和按钮 然后我使用菜单中的 打开
  • 使用基于Optional内容的流

    我从不受我控制的服务获取可能为空的地图 并且想要处理它 比方说 过滤 映射并减少到我需要的单个元素 问题 是否有从Optional到Stream的 链接 我尝试过 除其他外 return Optional ofNullable getMap
  • 膨胀类 android.support.design.internal.BottomNavigationView 时出错

    我正在制作我的第一个应用程序 这是一个简单的应用程序 带有启动屏幕和主要活动 现在我有两个构建变体 免费版本 活动底部有 Admob 横幅 付费版本 该应用程序不会在底部显示 admob 横幅 而是将其替换为用于切换活动的底部导航视图 我将
  • 如何在 Android 上设置 Google Drive API?

    我一直在尝试将 Google Drive 功能集成到我的应用程序中 但我无法使用任何内置功能 因此我相信我要么错过了一个步骤 要么做得不正确 我正在遵循官方的 Google 开发者指南 https developers google com
  • 无法查询 ContentResolver 以从 my_downloads 获取下载文件的名称,但在 all_downloads 中工作正常

    我的应用程序设置为激活一次具有扩展名的文件 myappdata被打开 它通过这个意图过滤器来实现这一点
  • Android,Volley请求,响应阻塞主线程

    使用 Volley 处理较大响应时会发生一些不好的事情 String url AppHelper DOMAIN service pages profile update json this infoTextView setText getS
  • JAAS keytab 配置的相对路径

    我有一个系统 其中 NET 客户端使用 Kerberos 针对 Java 服务器进行身份验证 一切正常 但我正在尝试改进服务器配置 目前一个keytab根目录中需要文件C 因为我的jaas配置文件看起来像这样 Server com sun
  • 如何在不显示父活动的情况下将一个全屏对话框片段替换为另一个全屏对话框片段?

    我有一个使用单个自定义 DialogFragment 类的活动 它的外观是数据驱动的 因此不同的调用看起来可能相当不同 它是 全屏 即 setStyle DialogFragment STYLE NO FRAME android R sty

随机推荐

  • 如何将 TextView 绘制到位图中(无需在显示器上绘制)

    根据主题 将 TextView 截图为位图 可以找到很多帖子 嗯 与我的问题不同的是 首先将视图绘制在显示器上 所有布局和测量工作都已完成 然后绘制到连接到位图的画布中 我只想从头开始创建一个 TextView 而不显示在渲染为位图的显示器
  • Pandas DataFrame:使用 Lambda 函数将 WKT 转换为新列中的 GeoJSON

    我有一些这种格式的数据 Dep Dest geom EDDF KIAD LINESTRING 3 961389 43 583333 3 968056 43 580 其中包含飞行轨迹 geom 列包含 WKT 格式的坐标 可以通过库转换它们g
  • Coq案例分析和函数返回子集类型的重写

    我正在做一个关于使用子集类型编写经过认证的函数的简单练习 想法是先写一个前驱函数 pred forall n n nat n gt 0 m nat S m n 1 然后使用这个定义给定一个函数 pred2 forall n n nat n
  • 为什么 Java ThreadLocal 变量应该是静态的

    我在这里阅读 Threadlocal 的 JavaDoc https docs oracle com javase 1 5 0 docs api java lang ThreadLocal html https docs oracle co
  • 尾递归是否一定需要累加器?

    例如 由于以下函数没有累加器 它仍然是尾递归吗 belong Ord a gt a gt a gt Bool belong a False belong a h t a h True otherwise belong a t 函数中的所有计
  • 使用 Alamofire 数据填充表单元格

    在一天的大部分时间里 我一直在尝试使用 Alamofire 并使用它来收集一些基于 API 的数据来填充表 我已经成功地将数据获取到我的 iOS 应用程序中 我可以 println 来查看它 但我一生都无法弄清楚使用我的数据填充正确数量的表
  • 将 3D 模型转换为 SceneJS JSON,包括纹理

    Motive我正在尝试使用 WebGL 创建一个小型演示应用程序 我选择使用 SceneJS 因为它看起来是一个简单的框架 并且足以满足此目的 我已经下载了几个 blend 模型 等 并使用 Blender 将它们导出为 Collada d
  • 为什么当目标状态或其父级通过 Promise 解析时 $state.go 不起作用

    我尝试使用解析加载父状态上的一些数据 并在应用程序运行时将用户重定向到默认状态 如下所示 app config stateProvider urlRouterProvider function stateProvider urlRouter
  • 如何在 JavaScript 中反转 JSON?

    task test created Date 1291676980607 task One More Big Test created Date 1291677246057 task New Task created Date 129174
  • 混合命名和未命名函数参数

    我有这个功能来验证 JWT 令牌 不是中间件 它说 package main import net http log fmt github com dgrijalva jwt go func ValidateToken w http Res
  • 如何选中反应测试库中的复选框?

    我似乎找不到太多 任何关于我想要实现的这个非常简单的事情的文档 我有一个下拉菜单display none 当我单击复选框时 它会变成display block我想要断言的是 当我单击复选框时 它会显示下拉列表 expect getByLab
  • SQL Server 2016 枢轴

    我有一个问题sql MS SQL 2016 和pivot功能 首先让我解释一下数据结构 示例tbl Preise 有多种价格 Preis 对于每个区域 Gebiet von Gebiet bis 在继电器 StaffelNr 所有连接到相同
  • Android - 检测长按结束

    我正在开发用户需要长时间按住按钮的应用程序 如何检测用户完成按下或移动触摸位置的时刻 Thanks 我认为最好的选择是对该按钮使用 onLongClickListener 和 onTouchListener 的组合 您需要在触摸侦听器上捕获
  • Rails 4 模型子文件夹

    我在 app models request book 文件夹中创建了模型 但 Book Request Status table name 返回表名称 statuses book request statuses 是正确的表名称 如何获得正
  • 随着扩展方法的出现,抽象类的吸引力是否降低了?

    NET 中扩展方法的一个有趣的方面是您可以将它们应用到接口 对我来说 我可以在接口附近定义功能 而无需定义使程序集混乱的抽象类 这似乎很好 我知道抽象类并没有过时 但是您对在代码中利用这种副作用有何看法 Example public sta
  • 在 Qt 中将多个小部件合并为一个

    我反复使用一对QComboBox and QListWidget在一个项目中 它们的交互是高度耦合的 当在组合框中选择一个项目时 列表会以某种方式进行过滤 我在多个对话框实现中复制粘贴这两个小部件之间的所有信号和插槽连接 我认为这不是一个好
  • 什么是杂注头?缓存页面..和 IE

    因此 我在 php 中发送标头来缓存我的页面 这也集成到我们的 CDN contendo akamai 中 我总是使用这个 pragma cache header 我见过各种例子也使用它 然而 我刚刚检查了 fiddler 来测试我们开发的
  • PHP $_FILES MIME 类型返回 null

    现在我正在尝试编写一个脚本 该脚本仅接受某些音频文件上传到服务器 但是 某些 MIME 类型将返回为 null 这是一些代码片段 PHP allowedExt array audio mp4a latm if isset POST prin
  • 项目同时使用MySQL和PostgreSQL时从JsonStringType切换为JsonBinaryType

    当需要从 PostgreSQL 切换到 MariaDB MySql 时 我遇到了 json 列的问题 我使用 Spring Boot JPA Hibernate hibernate types 52 我想要映射的表是这样的 CREATE T
  • BreakIterator 在 Android 中如何工作?

    我正在 Android 中制作自己的文本处理器 蒙古语的自定义垂直脚本 TextView 我以为我必须自己找到所有换行位置 以便我可以实现换行 但后来我发现BreakIterator https developer android com