如何更改字符串中的前两个单词?

How to change the first two words in the string?

提问人:CalebGates 提问时间:5/12/2023 更新时间:5/12/2023 访问量:95

问:

这个问题有点难以理解,因为我试图找到一种方法来满足我的应用程序(在这种情况下是俄语)中外语的语法要求。我试图在俄罗斯 Stackoverflow 上找到答案,但它已经死了,而且一直都是这样。这将是一篇很长的读物,但请耐心等待,因为我希望人们了解我在做什么,以及为什么除了硬编码一堆逻辑解决方法之外没有其他解决方案。

设置如下:

  1. 我有两个视图控制器(FirstVC 和 SecondVC)。
  2. 每个视图控制器都有一个表。
  3. 用户点击 FirstVC 中的单元格后,该单元格的内容将传递到 SecondVC 中的表头视图。
  4. 但是:SecondVC 的表头视图中的文本应该考虑俄语变格(俄语如此困难的原因之一)。
  5. SecondVC 的表头视图有两个字符串彼此重叠。最上面的那个写着“СПИСОК”,翻译为“LIST”。它是静态的,将永远保持原样。最下面的一个写着“участников”(翻译为“的参与者”),然后是字符串插值。总而言之,它应该读作“LIST of participants of the”,后跟从FirstVC的表单元格继承的任何事件名称。

这是最难的部分。在英语中,在大多数情况下,你可以把单词放在一起,然后你就有一个语法正确的句子。但从这个意义上说,俄语很奇怪,因为你必须修改单词本身来解释变格(我能想到的最接近的类比是当你使用单数和复数时。你不能说:“我有两瓶水”。您必须在“瓶子”中添加“s”。类似的东西。

幸运的是,我需要操作的单词通常是字符串中的第一个单词。然而,更罕见的是,人们可能不得不处理字符串中第一个和第二个单词的组合

多亏了 @Leo Dabus 在 Stackoverflow 上的一个回答,我设法从字符串中取出第一个单词,对其进行更改,然后添加到该字符串中的其余单词中。现在我需要一种方法来从字符串中取出前两个单词,以解决上面提到的那些罕见情况。如何使用相同的逻辑来做到这一点?

下面是 SecondVC 的代码:

import UIKit

class SecondVC: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!

var names: [Cell2Model] = []

var textForChanging: String = ""

var switchedFirstWord: String {
    switch textForChanging.firstWord {
    case "Соревнование": return "соревнования" //translates as "competition"
    default: return "none" } }

var restoOfTheName: String {
    var string = textForChanging
    string.enumerateSubstrings(in: string.startIndex..., options: .byWords) { (_, _, enclosingRange, stop) in
        string.removeSubrange(enclosingRange)
        stop = true }
    return string }

var adjustedEventNameText: String {
    return switchedFirstWord + " " + restoOfTheName }

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    
    // names will be taken from UITextFields on the fourth view controller
    names = [
        (Cell2Model(name: "Participant 1")),
        (Cell2Model(name: "Participant 2")),
        (Cell2Model(name: "Participant 3")) ]
    
    let tableHeader = UIView()
    tableView.tableHeaderView = tableHeader
    
    let labelOne = UILabel(frame: tableHeader.bounds)
    labelOne.text = "СПИСОК"
    labelOne.font = UIFont(name:"Arial-BoldMT", size: 17.0)
    labelOne.numberOfLines = 0
    labelOne.lineBreakMode = .byWordWrapping
    labelOne.textAlignment = .center
    labelOne.translatesAutoresizingMaskIntoConstraints = false
    
    let labelTwo = UILabel(frame: tableHeader.bounds)
    labelTwo.translatesAutoresizingMaskIntoConstraints = false
    labelTwo.text = "участников \(adjustedEventNameText)"
    labelTwo.font = UIFont(name:"Arial-BoldMT", size: 17.0)
    labelTwo.numberOfLines = 0
    labelTwo.lineBreakMode = .byWordWrapping
    labelTwo.textAlignment = .center
    labelTwo.translatesAutoresizingMaskIntoConstraints = false
    
    tableHeader.addSubview(labelOne)
    tableHeader.addSubview(labelTwo)

    let g = tableHeader.layoutMarginsGuide
    
    NSLayoutConstraint.activate([
        labelOne.topAnchor.constraint(equalTo: g.topAnchor, constant: 11.0),
        labelOne.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
        labelOne.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
        labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor, constant: 0.0),
        labelTwo.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
        labelTwo.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0), ])
    
    let c = labelTwo.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -11.0)
    c.priority = .required - 1
    c.isActive = true
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if let tableHeader = tableView.tableHeaderView {
        let fitSize: CGSize = CGSize(width: tableView.frame.width, height: .greatestFiniteMagnitude)
        let sz: CGSize = tableHeader.systemLayoutSizeFitting(fitSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
        let height: CGFloat = sz.height
        var headerFrame = tableHeader.frame
        if height != headerFrame.size.height {
            headerFrame.size.height = height
            tableHeader.frame = headerFrame
            tableView.tableHeaderView = tableHeader } } }

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return names.count }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "secondCell", for: indexPath) as! SecondCell
    let Name = names[indexPath.row]
    cell.label.text = Name.name
    return cell } }

extension StringProtocol {
var byWords: [SubSequence] { components(separated: .byWords) }

func components(separated options: String.EnumerationOptions)-> [SubSequence] {
    var components: [SubSequence] = []
    enumerateSubstrings(in: startIndex..., options: options) { _, range, _, _ in components.append(self[range]) }
    return components }

var firstWord: SubSequence? {
    var word: SubSequence?
    enumerateSubstrings(in: startIndex..., options: .byWords) { _, range, _, stop in
        word = self[range]
        stop = true }
    return word } }

如果需要,以下是 FirstVC 的代码:

import UIKit

class FirstVC: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!

var names: [Cell1Model] = []

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    
    // names will be taken from UITextFields on the third view controller
    names = [
        Cell1Model(name: "Соревнование по легкой атлетике"), // translates as "athletics competition (or "competition on athletics" to put it into the Russian words order)
        Cell1Model(name: "Благотворительное соревнование по легкой атлетике") // translates as "athletics charity competition" (or "charity competition on athletics" in the Russian words order)
    ]
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    if let vc = storyboard?.instantiateViewController(withIdentifier: "SecondVC") as? SecondVC {
        vc.textForChanging = names[indexPath.row].name!
        self.navigationController?.pushViewController(vc, animated: true) } }

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return names.count }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell
    let Name = names[indexPath.row]
    cell.label.text = Name.name
    return cell }

先谢谢你!

iOS Swift 子字符串 枚举

评论

0赞 lorem ipsum 5/12/2023
为什么要对字符串进行硬编码?你不能使用本地化吗?字符串文件还是字符串字典?
0赞 CalebGates 5/12/2023
对 Swift 非常陌生。甚至根本不知道这种可能性的存在。现在将阅读此内容。谢谢
0赞 lorem ipsum 5/12/2023
明白了,strings dict 是我们在英语中用来处理复数的。该文件负责所有事情。本地化有一个学习曲线,但值得付出努力。
0赞 matt 5/12/2023
俄语中的字符串字典可以处理零、一、二、几、多等

答:

0赞 Nebo 5/12/2023 #1

你可以使用 split(separator: “по”, maxSplits: 1) 结果数组中的第一个结果将是 “Соревнование” 和 “Благотворительно е соревнование” 在两个 Cell1Model 示例中

这些线路已经在 Switch 中检查过了,就像你以前一样

(无论如何,图像的实现是需要的) Xcode 中有一个用于单词变格的可本地化工具,也许它会对您有所帮助。

评论

0赞 CalebGates 5/12/2023
多谢!当我到达我的机器时会检查它!
0赞 CalebGates 5/12/2023
我阅读并观看了一些关于本地化的内容。我不太确定我是否绝对需要使用它,因为我最多只有 15-20 个案例。至于使用带有“по”分隔符的拆分,“по”不一定必须在字符串中。例如,考虑一个案例,您有“Заседание Федерального собрания”和“Оперативное заседание Федерального собрания”而不是“Соревнование по легкой атлетике”。我仍然认为最简单(也许不是最好的)方法是以某种方式从字符串中删除前两个单词
0赞 Nebo 5/13/2023
告诉我在“Заседание Федерального собрания”和“Оперативное заседание Федерального собрания”的情况下应该突出显示哪些词?您也可以通过 split(separator: “ ”) 获取 1 或 2 个第一个单词。但是对于这个程序,它必须以某种方式理解您需要在哪里使用 2 个单词,在哪里只需要一个单词
0赞 CalebGates 5/13/2023
你有电子邮件吗?我可以用俄语给你写信(会更容易一点)