如何用我的消息中的粗体文本替换星号包围的文本

How to replace text surrounded with stars with bolded text in my message

我正在制作一个聊天应用程序,我想添加一个功能,如果用户在两颗星 (*) 之间键入文本,则两颗星之间的文本 粗体

例如,如果用户键入消息 *this is bold* and this is not,则星之间的消息是粗体,如果不是粗体,则外面的消息。

我无法理解执行此操作的逻辑。我目前编写的代码是:

    String[] boldChecker = chatMessage.message.split("\*");
                for (int i = 0; boldChecker.length > i ; i++){
                    if ((i % 2) == 0) {
                        //is even and not bold
                        Log.d("boldArea - No",boldChecker[i]);
                    } else {
                        //is odd and bold
                        Log.d("boldArea - Yes",boldChecker[i]);
                    }
                }

这里chatmessage.message是用户输入的消息。我唯一知道的是要将文本设置为粗体,我需要使用 html.fromHtml(<b>bold text</b>).

您可以使用 StyleSpan 将文本的 加星标 部分加粗。

程序如下:

  1. 创建一个正则表达式,使文本包围在两颗星之间。

    这里是:"\*(.*?)\*"

  2. 获取与第 1 步中的正则表达式相匹配的消息文本的匹配器

    Pattern.compile("\*(.*?)\*").matcher(text)

  3. 迭代匹配器并使用StyleSpan加粗匹配组;但是问题是你需要在添加跨度之前删除开始,如果你使用匹配器索引,这将导致 IndexOutOfBoundsException;因此,我们将添加一个计数器来计算每次启动,并通过该计数器减少匹配器索引。

  4. 使用 setSpan()

    设置粗体跨度

代码演示注释:

private Matcher getMatchedStars(String text) {
    // matching start & end stars with a regex
    return Pattern.compile("\*(.*?)\*").matcher(text);
}

private Spannable getBolded(String text, Matcher matcher) {

    // Remove the starts from the text
    String noStarText = text.replace("*", "");

    // Create the Spannable from the no start text
    Spannable spannable = new SpannableString(noStarText);

    // count represents the current no. of removed stars
    int count = 1;

    // Iterate over the matched bolded text
    while (matcher.find()) {
        spannable.setSpan(new StyleSpan(BOLD),
                matcher.start() - count, // remove all previous stars from the start index
                matcher.end() - count - 1, // remove all previous stars from the end index
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        count += 2; // Add 2 to remove 2 stars from the current iteration (i.e. a complete bolded text is finished)
    }
    return spannable;
}

测试:

TextView tv = findViewById(R.id.my_textview);
String text = "Hello *Java* But here is *Android*, \n wait it's *Kotlin*";
Spannable spannable = getBolded(text, getMatchedStars(text));
tv.setText(spannable);

您可以继续使用此方法:

只需用 <b> </b> 标记替换 * 对,然后使用 Html.fromHtml(message) 将消息加粗,无论用户在 *

对之间键入什么消息

像这样:
let message = "*这是粗体*​​,这不是 *"
然后更改 message = "This is bold and this is not *"

您可以使用此代码进行替换


        // Let the message typed by the user is this
        String msg = "Hello friends, *This is the bold text* and this is not but *this is also bold* ** *";

        /**
         * @params firstIndex = index of the first * of the pair we are looking in the msg string
         *         secondIndex = index of the second * of the pair
         *         pairCount = to help us acknowledge that the pair *, we are looking for, is ready
         */
        int firstIndex = 0, secondIndex = 0, pairCount = 0;

        int i = 0;
        while (true){

            char c = msg.charAt(i);

            if (c == '*'){
                if (pairCount == 0) {
                    pairCount += 1;
                    firstIndex = i;
                }
                else if (pairCount == 1) {
                    pairCount += 1;
                    secondIndex = i;
                }
            }

            if (pairCount == 2){

                // replacing first * with <b>
                msg = msg.substring(0,firstIndex) + "<b>" + msg.substring(firstIndex+1);


                // replacing second * with </b>
                // increasing secondIndex by 2
                // because length of "msg" is increased by 2
                // after replacing <b> with *
                secondIndex += 2;
                msg = msg.substring(0,secondIndex) + "</b>" + msg.substring(secondIndex+1);


                // changing pair count to 0 as we have replaced the * pair
                // and are looking for new pair
                pairCount = 0;


                // Increasing i value to 5 because we have added <b> and </b> (total length = 7)
                // on replacement of * pairs (total length = 2)
                // 7 - 2 = 5
                i += 5;

            }

            i += 1;

            if (i >= msg.length()) break;
        }


        // Set the text to the TextView using Html 
        TextView tv = findViewById(R.id.your_textview_id);
        tv.setText(Html.fromHtml(msg));

结果

希望对您有所帮助